题目来源
思路
逆波兰表达式又称为后缀表达式
- 中缀
1 + 2 * 3
- 后缀
1 2 3 + *
我们需要将逆波兰表达式化为正常可计算的中缀表达式,再进行计算。题目所给的参数是后缀表达式,其操作的思路如下:
- 遇到操作数,入栈
- 遇到运算符,取栈顶两个连续数据进行计算,再将计算结果入栈
看起来不难,是因为这道题已经是简化后的版本,其所给后缀表达式中没有出现()
这种特殊优先级的操作。下面说一下把中缀转后缀的思路(本题没有涉及)
如何将中缀表达式转为后缀?
以这个中缀表达式为例
1 + 2 * 3 / 2 -5
我们都知道,运算顺序应该是先计算2*3
然后在计算6/2
,最后计算1+3-5
得出结果-1
因为* /
操作符的优先级高于加减,这里就需要注意这种情况。我们需要用一个栈来存放操作符
- 遇到操作数的时候 先输出
- 遇到操作符,和栈顶进行比较
- 如果栈为空/操作符优先级高于栈顶,入栈
- 操作符优先级低于栈顶或和栈顶相同,出栈顶操作符
- 最后将栈中的操作符全部出栈,就可以获得后缀表达式
用上面这个思路走一遍,即为下面的情况(不知道这样写的大家能不能看明白)
最终得到的结果如下
1 2 3 * 2 / + 5 -
即需要的后缀表达式
我们可以用本题代码测试一下这个用例,得出的结果也是-1
,正确!
完整代码
//https://leetcode.cn/problems/evaluate-reverse-polish-notation/submissions/
//150逆波兰表达式
class Solution {
public:
int evalRPN(vector<string>& tokens) {
stack<int> s;
for(auto& ch : tokens)
{
if(ch=="+"||ch=="-"||ch=="*"||ch=="/")
{
int right=s.top();
s.pop();
int left=s.top();
s.pop();
switch(ch[0])
{
case '+':
s.push(left+right);
break;
case '-':
s.push(left-right);
break;
case '*':
s.push(left*right);
break;
case '/':
s.push(left/right);
break;
default:
break;
}
}
else{
s.push(stoi(ch));
}
}
return s.top();
}
};