数据结构实验--栈与队列 --后缀表达式求值

实验内容及要求:

从键盘输入后缀表达式(运算符和操作数建议以字符串形式输入,空格作为分隔符),计算并输出后缀表达式的求值结果。 

基本要求:实现 +, -, *, /四个二元运算符;

          实现+, -两个一元运算符(即正、负号);

          操作数用整数表示。

提高要求:输出对应的前缀表达式。

每位同学可必须实现基本要求,可选择实现提高要求;程序可不处理表达式语法错误。

实验目的:掌握堆栈在表达式求值中的应用。

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<string>
#include<sstream>
#include<vector>
using namespace std;


//节点结构体
typedef struct Node
{
	int data;
	struct Node* next;
}SNode;
//定义栈结构OPND来储存操作数和运算结果
typedef struct Stack {	
	SNode* top;
	int stackSize;
}OPND;
//初始化栈
bool InitStack(OPND * & S) {
	S->top = NULL;
	if (S->top != NULL)
		return false;
	S->stackSize = 0;
	return true;
}
//压栈
bool Push(OPND * & S, int e) {
	SNode* newNode = new Node;
	newNode->data = e;
	newNode->next = S->top;
	S->top = newNode;
	S->stackSize++;
	return true;
}
bool Pop(OPND* & S,int &e) {
	if (S->stackSize == 0)
		return false;
	SNode* p = S->top;
	e = p->data;
	S->top = p->next;
	delete p;
	S->stackSize--;
	return true;
}
int Operate(int a1, int a2, char op)
{
	switch (op)
	{
	case '+':
		return a1 + a2;
		break;
	case '-':
		return a1 - a2;
		break;
	case '*':
		return a1 * a2;
		break;
	case '/':
		return a1 / a2;
		break;
	}
}
int GeTResult(OPND* & S)
{
	if (S->stackSize==0)
		return 0;
	return S->top->data;
}

int main() {

	string arr;
	OPND * d1 = new OPND;
	InitStack(d1);
	cout << "从键盘输入后缀表达式(运算符和操作数建议以字符串形式输入,空格作为分隔符)"
		<< endl;
	getline(cin, arr);
	istringstream ss(arr);
	vector<string> words;
	string word;
	while (ss >> word) {
		words.push_back(word);
	}
	for (string x : words) {
		if (x == "-" ||x == "+" ||  x=="*" || x =="/") {
			const char* p = x.c_str();
			int a1 = 0, a2 = 0;
			Pop(d1, a1);
			Pop(d1, a2);
			//将两个操作数取出来之后进行相应的运算。
			int result = Operate(a2, a1, p[0]);
			Push(d1, result);
		}
		
		else {
			//将字符串类型转化为int型
			stringstream geek(x);
			int p;
			geek>>p;
			Push(d1, p);
		}
	}
	cout << "表达式计算的结果是:" << GeTResult(d1) << endl;
	return 0;
}


输入:6 5 2 3 + 8 * + 3 + *

运行结果

 本人实力有限,做法有些复杂,还望大哥们不吝赐教!!!

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 是一种特殊的线性结构,后缀式求值中需要用到。在后缀表达式中,遇到操作数时将其压入中,遇到操作符时从顶取出两个操作数进行计算,将计算结果再压入中,直到最终得到表达式的值。这种方法避免了操作符优先级的问题,也不需要括号,因此简化了计算过程。 ### 回答2: 后缀式也称为逆波兰式,是一种无需考虑运算符优先级也不需要括号即可确定完整运算顺序的表达式表示方法。后缀式的运算可以使用队列的实现方式。 在后缀式求值的过程中,首先需要将中缀表达式转换成后缀式。具体操作为,从左到右扫描中缀表达式,遇到操作数则输出到后缀式中;遇到操作符时,判断其与顶操作符的优先级,如果该操作符优先级不高于顶操作符,则将顶操作符弹出并输出到后缀式中,直到遇到顶操作符优先级比该操作符低或者相等时,再将该操作符入。如果遇到左括号,则直接将其入;如果遇到右括号,则将中左括号上面的操作符依次弹出并输出到后缀式中,直到遇到左括号,左右括号不输出到后缀式中。 将中缀表达式转换成后缀式之后,就可以根据后缀式进行求值了。具体操作为,从左到右扫描后缀表达式,遇到操作数则入;遇到操作符时,弹出顶的两个操作数,先弹出的作为右操作数,后弹出的作为左操作数,根据遇到的操作符进行计算,将结果入;最后扫描结束后,中仅有一个元素,即为表达式的计算结果。 使用队列的实现方式均可以实现后缀式求值,具体实现方式也会略有不同。使用的实现方式较为简单,只需要设置一个用于存储操作数和中间结果,按照后缀式中的顺序进行遍历,遇到数字则压入中,遇到操作符时则弹出顶的两个数字进行计算并将结果压入中,最终中仅剩一个元素,即为表达式的计算结果。 在实现代码时需要注意一些问题,如数字可能是多位数,需要处理好每一位;中缀表达式中可能存在负数的情况,需要进行转换;在弹出顶元素时需要注意是否为空等等。 总之,队列三:后缀式求值是数据结构实验中的一个重要实验,在实现过程中需要理解后缀式的特点以及使用队列实现后缀式求值的具体过程,也需要注意在实现代码时处理好各种情况和异常情况,以保证程序的正确性和稳定性。 ### 回答3: 后缀式是一种将算术表达式中每个操作符都放在其相关操作数之后的形式。例如,中缀表达式“(5 + 4)× 3”可以转换为后缀表达式“5 4 + 3 ×”。 在本实验中,我们需要实现一个后缀表达式求值器,以计算给定的后缀表达式的值。 实现该求值器的主要数据结构是一个。遍历后缀表达式,如果遇到一个操作数,则将其压入中。如果遇到一个操作符,则弹出顶的两个操作数进行计算,并将结果压入中。最后,顶的元素就是后缀表达式的值。 下面以‘5 4 + 3 ×’为例来说明该算法的具体步骤: 1. 从左到右依次遍历后缀表达式,遇到5,将其压入中; 2. 遇到4,将其压入中; 3. 遇到+,弹出顶的两个元素4和5,计算5+4=9,将结果9压入中; 4. 遇到3,将其压入中; 5. 遇到×,弹出顶的两个元素9和3,计算9×3=27,将结果27压入中; 6. 最后中只剩下一个元素27,该元素即为后缀表达式的值。 可以看出,后缀表达式求值算法的时间复杂度为O(n),其中n是后缀表达式的长度。 在实现算法时,还需要考虑以下一些问题: 1. 如何判断一个字符是操作符还是操作数? 2. 如何处理多位数字? 3. 如何处理负数? 4. 如何处理除0错误? 以上问题一一解决后,就可以完成后缀表达式求值器的实现。通过实验,可以熟悉栈和队列的应用场景,加深对数据结构的理解,提高编程技能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值