【leetcode】150. 逆波兰表达式求值
慕雪年华

题目来源

150. 逆波兰表达式求值

image

思路

逆波兰表达式又称为后缀表达式

  • 中缀 1 + 2 * 3
  • 后缀 1 2 3 + *

我们需要将逆波兰表达式化为正常可计算的中缀表达式,再进行计算。题目所给的参数是后缀表达式,其操作的思路如下:

  • 遇到操作数,入栈
  • 遇到运算符,取栈顶两个连续数据进行计算,再将计算结果入栈

看起来不难,是因为这道题已经是简化后的版本,其所给后缀表达式中没有出现()这种特殊优先级的操作。下面说一下把中缀转后缀的思路(本题没有涉及)

中缀表达式转为后缀

手工做法:

以例2给出的中缀表达式为例,中缀表达式转换为后缀表达式的手工做法为:

按照运算符的优先级对所有的运算单位加括号。例: ((a/b) + (((c*d) - (e*f))/g))
把运算符号移动到对应括号的后面,然后去掉括号。例:((ab)/ (((cd)*(ef)*)-g)/+,去掉括号ab/cd*ef*-g/+


以这个中缀表达式为例

1
1 + 2 * 3 / 2 -5

我们都知道,运算顺序应该是先计算2*3然后在计算6/2,最后计算1+3-5得出结果-1

因为* /操作符的优先级高于加减,这里就需要注意这种情况。我们需要用一个栈来存放操作符

  • 遇到操作数的时候 先输出
  • 遇到操作符,和栈顶进行比较
    • 如果栈为空/操作符优先级高于栈顶,入栈
    • 操作符优先级低于栈顶或和栈顶相同,出栈顶操作符
  • 最后将栈中的操作符全部出栈,就可以获得后缀表达式

用上面这个思路走一遍,即为下面的情况(不知道这样写的大家能不能看明白)

image

最终得到的结果如下

1
1 2 3 * 2 / + 5 -

即需要的后缀表达式

我们可以用本题代码测试一下这个用例,得出的结果也是-1,正确!

image

后缀转中缀

https://blog.csdn.net/qq_29462849/article/details/93652583

image

完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
//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();
}
};

image