后缀表达式求值

该博客介绍了一种后缀表达式(逆波兰式)的计算方法,通过使用操作数栈来处理运算。当遇到运算符时,根据其优先级进行相应的运算。在计算过程中,对除数为零、运算符数量不正确等错误进行了处理。示例展示了不同错误情况下的输出结果,如除以零时输出`Error:X/0`,运算符过多时输出`ExpressionError:X`。
摘要由CSDN通过智能技术生成

后缀表达式,又称逆波兰式,指的是不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行。

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

建立一个操作数栈S。然后从左到右读表达式,如果读到操作数就将它压入栈S中,如果读到n元运算符(即需要参数个数为n的运算符)则取出由栈顶向下的n项操作数进行运算,再将运算的结果代替原栈顶的n项压入栈中。重复上面过程,如果后缀表达式读完且栈中只剩一个操作数,则该数就是运算结果;如果后缀表达式读完但是栈中操作数多于一个,则后缀表达式错误;如果栈中操作数只剩一个,但是后缀表达式还未读完且当前运算符为双元操作符,则后缀表达式同样错误。

输入格式:

在一行中输入一个以#号结束的非空后缀式,#不属于表达式的一部分,操作数和运算符都以空格分隔,运算数为绝对值不超过100的整数,运算符仅有+、-、*、/ 四种。

输出格式:

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

如果执行除法时出现分母为零的非法操作,则在一行中输出: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

#include<iostream>
#include<algorithm>
#include<string>
#include<stack>

using namespace std;

stack<int> num;

void eval(char c)
{
    auto b=num.top(); num.pop();
    auto a=num.top(); num.pop();
    int x;
    if(c=='+') x=a+b;
    else if(c=='-') x=a-b;
    else if(c=='*') x=a*b;
    else x=a/b;
    num.push(x);
}
int main()
{
    string str;
    getline(cin,str);           //把空格也读入,若是cin>>str遇空格就结束输入
    bool check=true;            //是否有解
    for(int i=0;str[i]!='#';i++)
    {
        auto c=str[i];
        
        if(c==' ') continue;        //跳过空格
        else if(isdigit(c)||(c=='-'&&isdigit(str[i+1])))
        {
            int x=0,j=i;
            bool flag=false;        //是否为负数
            if(!isdigit(c))
            {
                j++;                
                flag=true;
            }
            while(isdigit(str[j])) x=x*10+str[j++]-'0';
            if(flag) x=-x;          //是负数
            num.push(x);
            i=j;                    //因为i会再+1,下次直接跳过空格
        }
        else
        {
            if(num.size()>=2&& (c!='/'||num.top()!=0)) eval(c);     //操作合法
            else if(c=='/'&&num.top()==0)                   //除以0
            {
                num.pop();
                cout<<"Error: "<<num.top()<<"/0";
                check=false;
                break;
            }
            else
            {
                cout<<"Expression Error: "<<num.top();              //运算符过多
                check=false;
                break;
            }
        }
    }
    if(num.size()!=1 && check) cout<<"Expression Error: "<<num.top();       //运算符过少
    else if(check)cout<<num.top();      //有解
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值