一、题目

根据 逆波兰表示法,求表达式的值。有效的算符包括 +、-、*、/ 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。

说明:

  • 整数除法只保留整数部分。
  • 给定逆波兰表达式总是有效的。即表达式总会得出有效数值且不存在除数为 0 的情况。

【LeetCode150】逆波兰表达式求值(栈)_逆波兰表达式


提示:

  • 1 <= tokens.length <= 104
  • tokens[i] 要么是一个算符("+"、"-"、"*" 或 “/”),要么是一个在范围 [-200, 200] 内的整数

逆波兰表达式介绍:
逆波兰表达式是一种后缀表达式,所谓后缀就是指算符写在后面。

  • 平常使用的算式则是一种中缀表达式,如 ( 1 + 2 ) * ( 3 + 4 ) 。
  • 该算式的逆波兰表达式写法为 ( ( 1 2 + ) ( 3 4 + ) * ) 。

逆波兰表达式主要有以下两个优点:

  • 去掉括号后表达式无歧义,上式即便写成 1 2 + 3 4 + * 也可以依据次序计算出正确结果。
  • 适合用栈操作运算:遇到数字则入栈;遇到算符则取出栈顶两个数字进行计算,并将结果压入栈中。

二、思路

因为直接给出逆波兰表达式了,即后缀表达式,所以直接遇到数字就入栈,遇到运算符号时,就让栈中的两个数字进行相关运算。直到全部运算完毕。

每次判断当前的符号是否为数字稍稍麻烦,因为运算的数字可能有多位数(这样直接判断数字有点麻烦),那就直接判断当前符号是否为运算符。

细节:注意在​​switch​​​中的每个case结尾需要加上​​break​​,否则会执行多个case。

c++的stl:
(1)​​​isalpha()​​​ 用来判断一个字符是否是英文字母,相当于 ​​isupper(c)||islower(c)​​​。
(2)如果使用​​​atoi​​​时记得加上​​c_str()​​​,如​​atoi(str.c_str())​​。

三、代码

class Solution {
public:
int evalRPN(vector<string>& tokens) {
stack<int> stk;
int n = tokens.size();
for(int i = 0; i < n; i++){
string& str = tokens[i];
//如果为数字则入栈
if(!isCalCha(str)){
stk.push(atoi(str.c_str()));
}else{
int num2 = stk.top();
stk.pop();
int num1 = stk.top();
stk.pop();
switch(str[0]){
case '+':
stk.push(num1 + num2);
break;
case '-':
stk.push(num1 - num2);
break;
case '*':
stk.push(num1 * num2);
break;
case '/':
stk.push(num1 / num2);
break;
}
}
}
return stk.top();
}
//判断是否为运算符
bool isCalCha(string str){
if(str == "+" || str == "-" || str == "*" || str == "/"){
return true;
}else{
return false;
}
}
};

【LeetCode150】逆波兰表达式求值(栈)_逆波兰表达式_02