后缀表达式求值

该博客介绍了一种后缀表达式(逆波兰式)的计算方法,通过使用栈来处理运算。在计算过程中,遇到数字时将其压栈,遇到运算符则取出栈顶的两个元素进行运算并把结果压回栈。文章详细阐述了处理除数为零、运算符数量错误等异常情况,并提供了一个C++实现的示例代码。在输入一个以#号结束的非空后缀表达式后,程序会输出计算结果或错误信息。
摘要由CSDN通过智能技术生成

后缀表达式,又称逆波兰式,指的是不包含括号,运算符放在两个运算对象的后面,所有的计算按

运算符出现的顺序,严格从左向右进行。

运用后缀表达式进行计算的具体做法:

      建立一个操作数栈S。然后从左到右读表达式,如果读到操作数就将它压入栈S中,如果读到n

元运算符(即需要参数个数为n的运算符)则取出由栈顶向下的n项操作数进行运算,再将运算的结果

代替原栈顶的n项压入栈中。重复上面过程,如果后缀表达式读完且栈中只剩一个操作数,则该数

就是运算结果;如果后缀表达式读完但是栈中操作数多于一个,则后缀表达式错误;如果栈中操作

数只剩一个,但是后缀表达式还未读完且当前运算符为双元操作符,则后缀表达式同样错误。

输入格式:

在一行中输入一个以#号结束的非空后缀式,#不属于表达式的一部分,操作数和运算符都以空格分

隔,运算数为绝对值不超过100的整数,运算符仅有+、-、*、/ 四种。

输出格式:

输出后缀式计算结果,所有的计算都只取结果的整数部分。题目保证计算的中间和最后结果的绝对

值都不超过10^​9​​。

如果执行除法时出现分母为零的非法操作,则在一行中输出:Error: X/0,X是当时的分子。

如果后缀表达式中运算符多了或者少了,则在一行中输出:Expression Error: X,X是当时栈顶元

素。

输入样例1:

5 -2 + 3 * #

输出样例1:

9

输入样例2:

5 -2 2 + / #

输出样例2:

Error: 5/0

输入样例3:

5 -1 3 + / - * #

输出样例3:

Expression Error: 2

题目解析:

        输入字符串,如果是数字就push到栈中,如果遇到运算符(题目中已给出,都是二元运算

符),然后从栈顶中取出两个元素,进行运算,如果在这个过程中出现运算符多了或者少了,除数

为0的时候都是错误情况,打印栈顶退出。运算之后,将结果push到栈中。遇到#号结束。

 例如:样例1:

5 -2 + 3 * #

         遇到5, -2,就push到栈中,此时栈中有两个元素,为5, -2,遇到+,从栈顶中取出两个元

素,进行运算,5 +(-2) = 3,获得结果之后,将结果push到栈中,现在栈中只剩下了一个元素

3,然后继续输入,3,push到栈中,此时栈中有两个元素,遇到 ‘*’ 号,从栈顶中取出两个元素,

3, 3,进行乘法运算,3 * 3  = 9,然后将 9 push到栈中,栈中只剩下了一个元素,9,然后继续

输入,此时遇到了 ‘#’ 号,结束读入。

        此时栈中只有一个元素表示运算正确,打印栈顶元素,即为结果,

上代码

#include <iostream>
#include <stack> 
#include <string>
#include <sstream>
using namespace std;
typedef long long LL;
stack<LL> sta;

LL n; 
LL SwVal(LL x, LL y, char ch);//计算加减乘除的值 
 
int main(){
    string s;
    while(cin >> s){
    	if(s == "#") break;//遇到#符号结束 读入 
		//遇到数字就push进去,否则就计算 
    	if(s != "+" && s != "-" && s != "*" && s != "/"){	
			stringstream stream;
    		stream << s;stream >> n;//将字符串读出为数字 ,并 push 进去 
    		sta.push(n);
		}
    	else{ 
			LL x = sta.top();sta.pop();//先拿出一个元素 
            //如果拿了一个元素之后就没有元素了,那么就出错了,打印已拿出栈顶元素x 
			if(sta.empty()){
                cout << "Expression Error: " << x << endl;
                exit(0);
            }
			LL res = sta.top();sta.pop();//拿出第二个元素 
	    	res = SwVal(res, x, s[0]);//计算值,并push到栈中 
			sta.push(res);
		}
	}
	if(sta.size() < 2) cout << sta.top() << endl;//栈中元素只有一个,打印x,计算成功 
    else{//判断计算之后是否只剩下一个元素,如果否,也是出错,打印已拿出栈顶元素x 
        cout << "Expression Error: " << sta.top() << endl;
		exit(0);
    }
    return 0;
}
 
LL SwVal(LL x, LL y, char ch){ 
	switch(ch){
		case '+': return x + y;
		case '-': return x - y;
		case '*': return x * y;
		case '/':
			//遇到 /0的情况,出现错误,打印错误情况 
            if(y == 0){
				cout << "Error: " << x << "/0" << endl;
				exit(0);
			}
            return x / y;	
	}
}

  • 17
    点赞
  • 69
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值