题目(leecode T150):
给你一个字符串数组 tokens
,表示一个根据 逆波兰表示法 表示的算术表达式。
请你计算该表达式。返回一个表示表达式值的整数。
注意:
- 有效的算符为
'+'
、'-'
、'*'
和'/'
。 - 每个操作数(运算对象)都可以是一个整数或者另一个表达式。
- 两个整数之间的除法总是 向零截断 。
- 表达式中不含除零运算。
- 输入是一个根据逆波兰表示法表示的算术表达式。
- 答案及所有中间计算结果可以用 32 位 整数表示。
方法:逆波兰表达式是一种后缀表达式,所谓后缀表达式就是运算符号在运算数的后面。如3 5 +,其实表示的是3 + 5的意思。而我们常见的3 + 5是中缀表达式,比较方便我们人的理解,但其实对于计算机来说,后缀表达式是更容易理解的。因为在计算机内部后缀表达式可以通过栈的方式来进行计算,具体方法如下:
后缀表达式中前两个是数字,后面跟着的是运算符号,因此我们可以在遇到数字的时候,将其进行入栈,当遇到运算符号的时候,我们出栈两个元素,然后根据运算符号进行正常的运算,随后再将其入栈, 重复此操作一直到处理完数组之后,栈中剩下的那个数字就是我们的逆波兰表达式的运算结果,将其返回即可。在这当中有一个小细节需要注意,就是两个数字运算顺序的问题,对于加法和乘法来说,两个操作数的顺序其实是没有影响的,但是对于减法和除法来说,运算是有顺序的,比如5 3 /,正确的顺序应该是5/3,但是在字符数组入栈的时候,5比3先入栈了,取出的时候,5就比3后取出,因此按照取出的顺序num1和num2,我们应该是num2/num1,减法同理。
题解:
class Solution {
public:
int evalRPN(vector<string>& tokens) {
stack<long long> st;
for(int i = 0; i < tokens.size(); i++){
if(tokens[i] == "+" || tokens[i] == "-" || tokens[i] == "*" || tokens[i] == "/"){ //运算符则进行运算
long long num1 = st.top();
st.pop();
long long num2 = st.top();
st.pop();
if(tokens[i] == "+") st.push(num2 + num1);
if(tokens[i] == "-") st.push(num2 - num1); //注意是num2和num1的操作顺序
if(tokens[i] == "*") st.push(num2 * num1);
if(tokens[i] == "/") st.push(num2 / num1);
}else{
st.push(stoll(tokens[i])); //数字则入栈
}
}
int result = st.top();
st.pop();
return result;
}
};