后缀表达式求值:建立一个操作数栈S。然后从左到右读表达式,如果读到操作数就将它压入栈S中,如果读到n元运算符(即需要参数个数为n的运算符)则取出由栈顶向下的n项操作数进行运算,再将运算的结果代替原栈顶的n项压入栈中。重复上面过程,如果后缀表达式读完且栈中只剩一个操作数,则该数就是运算结果;如果后缀表达式读完但是栈中操作数多于一个,则后缀表达式错误;如果栈中操作数只剩一个,但是后缀表达式还未读完且当前运算符为双元操作符,则后缀表达式同样错误。
输入格式:
在一行中输入一个以#号结束的非空后缀式,#不属于表达式的一部分,操作数和运算符都以空格分隔,运算数为绝对值不超过100的整数,运算符仅有+、-、*、/ 四种。
输出格式:
输出后缀式计算结果,所有的计算都只取结果的整数部分。题目保证计算的中间和最后结果的绝对值都不超过109。如果执行除法时出现分母为零的非法操作,则在一行中输出:Error: X/0,X是当时的分子。如果后缀表达式中运算符多了或者少了,则在一行中输出:Expression Error: X,X是当时栈顶元素。
输入样例1:5 -2 + 3 * # 输出:9
输入样例2:5 -2 2 + / # 输出:Error: 5/0
输入样例3:5 -1 3 + / - * # 输出Expression Error: 2
- //用于存放操作数的栈
- int OPND[100];
- int top=0;
- //运算操作
- int operate(int a,char operate,int b)
- //计算表达式函数,如果出现错误的表达式返回false,表达式正确返回true,并且表达式的值最终会存在栈里。
- bool caculate(string s);
- int main()
- {
- string s;
- top=0;
- getline(cin,s);//可以接受空格
- if(caculate(s))
- {
- cout<<"表达式的值为:"<<OPND[0];
- }
- }
其实不用特意的写这些函数,下面几个操作都可以用一个语句完成,写成函数是为了方便阅读
- //栈的操作
- void push(int num)
- {
- OPND[top++]=num;
- }
- int pop()
- {
- return OPND[--top];
- }
- int GetTop()
- {
- return OPND[top-1];
- }
- int operate(int a,char operate,int b)
- {//不出现/0的情况
- int ans;
- if(operate=='+')
- ans=a+b;
- else if(operate=='-')
- ans=a-b;
- else if(operate=='*')
- ans=a*b;
- else
- ans=a/b;
- return ans;
- }
我是一个字符一个字符扫描的,有的人习惯将表达式的string串以空格分成多个string串,对每个string串扫描,这样也可以。
- bool caculate(string s)
- {
- int a,b,num=0,i=0;
- int sign=1;//记录数字符号
- char thea;
- while(s[i]!='#')
- {
- if(s[i]>='0'&&s[i]<='9')
- {//遇到数字开始构造
- num=10*num+s[i]-'0';
- }
- if(s[i]=='-'&&s[i+1]>='0'&&s[i+1]<='9')
- {//'-'后面跟着数字,说明遇到了负数 ,标记符号
- sign=-1;
- }
- else if(s[i]=='+'||s[i]=='-'||s[i]=='/'||s[i]=='*')
- {
- if(top==0)
- {//没有操作数
- cout<<"Expression Error: No operand!";
- return false;
- }
- else if(top<2)
- {//操作数不够
- cout<<"Expression Error: "<<OPND[top-1];
- return false;
- }
- b=pop();
- a=pop();
- if(b==0&&s[i]=='/')
- {//除数为零的情况
- cout<<"Expression Error: "<<a<<"/"<<b;
- return false;
- }
- int ans=operate(a,s[i],b);//先抛出的做第二操作数
- push(ans);
- }
- else if(s[i-1]>='0'&&s[i-1]<='9'&&s[i]==' ')
- {//当前字符是空格并且前面字符是数字
- num*=sign;
- push(num);
- num=0;
- sign=1;
- }
- i++;
- }
- if(top>1)
- {//扫描结束后栈里的数大于一个,说明表达式有误
- cout<<"Expression Error: "<<OPND[top-1];
- return false;
- }
- return true;
- }
- #include<iostream>
- using namespace std;
- int OPND[100];
- int top=0;
- //栈的操作
- void push(int num)
- {
- OPND[top++]=num;
- }
- int pop()
- {
- return OPND[--top];
- }
- int GetTop()
- {
- return OPND[top-1];
- }
- int operate(int a,char operate,int b)
- {//不出现/0的情况
- int ans;
- if(operate=='+')
- ans=a+b;
- else if(operate=='-')
- ans=a-b;
- else if(operate=='*')
- ans=a*b;
- else
- ans=a/b;
- return ans;
- }
- bool caculate(string s)
- {
- int a,b,num=0,i=0;
- int sign=1;//记录数字符号
- char thea;
- while(s[i]!='#')
- {
- if(s[i]>='0'&&s[i]<='9')
- {//遇到数字开始构造
- num=10*num+s[i]-'0';
- }
- if(s[i]=='-'&&s[i+1]>='0'&&s[i+1]<='9')
- {//'-'后面跟着数字,说明遇到了负数 ,标记符号
- sign=-1;
- }
- else if(s[i]=='+'||s[i]=='-'||s[i]=='/'||s[i]=='*')
- {
- if(top==0)
- {//没有操作数
- cout<<"Expression Error: No operand!";
- return false;
- }
- else if(top<2)
- {//操作数不够
- cout<<"Expression Error: "<<OPND[top-1];
- return false;
- }
- b=pop();
- a=pop();
- if(b==0&&s[i]=='/')
- {//除数为零的情况
- cout<<"Expression Error: "<<a<<"/"<<b;
- return false;
- }
- int ans=operate(a,s[i],b);//先抛出的做第二操作数
- push(ans);
- }
- else if(s[i-1]>='0'&&s[i-1]<='9'&&s[i]==' ')
- {//当前字符是空格并且前面字符是数字
- num*=sign;
- push(num);
- num=0;
- sign=1;
- }
- i++;
- }
- if(top>1)
- {
- cout<<"Expression Error: "<<OPND[top-1];
- return false;
- }
- return true;
- }
- int main()
- {
- string s;
- top=0;
- getline(cin,s);//可以接受空格
- // cout<<s;
- if(caculate(s))
- {
- cout<<"表达式的值为:"<<OPND[0];
- }
- }