后缀表达式,又称逆波兰式,指的是不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行。
运用后缀表达式进行计算的具体做法:
建立一个操作数栈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;
}