题目描述
所谓后缀表达式是指这样的一个表达式:式中不再引用括号,运算符号放在两个运算对象之后,所有计算按运算符号出现的顺序,严格地由左而右新进行(不用考虑运算符的优先级)。
如:30∗(5–2)+7对应的后缀表达式为:30 . 5 . 2 . – * 7 . + @。’@’为表达式的结束符号。‘.’为操作数的结束符号。
输入
一行后缀表达式,@结尾。
输出
表达式的值
输入样例
3.5.2.-*7.+@
输出样例
16
提示
对100%的数据,表达式长度不超过1000,运算符号包括加减乘除,且确保运算均为合法运算(除数不为0),操作数及中间运算结果均为int整数。
---------------------------------------------------------------------------------------------------------------------------------
思路
我们来分析一下,我们要计算后缀表达式,是不是在遇到符号的时候,把最后出现的两数字进行运算?因为后缀表达式是直接把运算符号放在两个运算对象之后
我们来算一下这个后缀表达式:
30 . 5 . 2 . – * 7 . + @
先读入30,5,2,这是遇到了减号,将最后读入的5和2进行减法运算,得出答案3,这是,5 2 -这个算式已经算完了,我们是不是可以直接把3存进去?为什么?这是不是和我们平常算数一样,比如我们算2*(2-1),我们把2-1算完,我们会把2-1换成数字1,把算式换成2*1,所以,我们可以直接把3存进去
现在,我们已经存了30,3读到乘号,进行运算,30*3=90,现在存了90,读入7,现在存了90,7,遇到加号,进行计算,90+7=97,得出最终答案97
最后我们想一下,我们怎么存数字呢?
因为我们计算都是要找最后读入的两个数计算,符合栈先进后出的规则,所以我们可以用栈来存数字,遇到符号把最上面两个数拿出来算,再把结果放回去
这道题的思路应该还是很简单的吧?
---------------------------------------------------------------------------------------------------------------------------------
代码:
#include <bits/stdc++.h>
using namespace std;
int main(){
char dr;//因为读入的都是字符,我们用一个dr来存每个字符
long long shuzi=0;//shuzi来存读入到的数字
stack<long long> a;
while(cin>>dr,dr!='@'){
if(dr>='1'&&dr<='9'){//如果我们发现读入到了数字
shuzi*=10;//将shuzi*10,为要添加的各位让位置
shuzi+=dr-'0';//添加个位
}
if(dr=='.'){//如果读入到了.
a.push(shuzi);//说明读入结束了,将数字存进栈里
shuzi=0;//数字存好了,就要在存新数字,把shuzi设成0,才能再存新数字
}
if(dr=='+'){//读到了加号
long long c,d;//用c和d来记录最上面的两个数字
d=a.top();a.pop();//因为最后读入的是第二个加数,所以存在d里面
c=a.top();a.pop();//因为第二个加数已经弹出了,现在的栈顶就是第一个加数
c=c+d;//用c来存储计算结果
a.push(c);//将结果存起来
}
if(dr=='-'){//读到减号,进行运算
long long c,d;
d=a.top();a.pop();
c=a.top();a.pop();
c=c-d;
a.push(c);
//跟上面一样
}
if(dr=='*'){//读到乘号进行计算
long long c,d;
d=a.top();a.pop();
c=a.top();a.pop();
c=c*d;
a.push(c);//跟上面一样
}
if(dr=='/'){//读到除号,进行计算
long long c,d;
d=a.top();a.pop();
c=a.top();a.pop();
c=c/d;
a.push(c);//跟上面一样
}
}
cout<<a.top();//算完后,答案还是存在a里
//因为a里只有一个数(其他的数都在计算时被弹出了),所以输出栈顶
return 0;
}