LeetCode 150题解 | 逆波兰表达式求值
逆波兰表达式求值
- 一、题目链接
- 二、题目
- 三、算法原理
- 四、编写代码
一、题目链接
逆波兰表达式求值
二、题目
三、算法原理
按顺序读中缀表达式的运算是很麻烦的,因为中缀表达式并不是按照顺序运算,要考虑运算符优先级的问题。例如:
1 + 2 - 3
1 + 2 * 3
1 + 2 * (3 - 4)
后缀表达式比起中缀表达式的特点:操作数的顺序是不变的,只调整运算符的顺序,操作符要按照优先级排列,运算符要紧紧挨着放在对应的两个操作数后面。所以一般给出一个中缀表达式是可以写出它对应的后缀表达式的。我们可以试着把上述中缀表达式转换成后缀表达式:
1 2 + 3 -
1 2 3 * +
1 2 3 4 - * +
本身这题并不难,因为题中是直接给你后缀表达式了,不需要自己转换。
用代码实现中缀表达式转换成后缀表达式很复杂,本题下面"相似题目"有一道困难题就需要把中缀表达式转换成后缀表达式再计算。相关知识点及解题过程会放在"补充知识"中。
思路:建立一个栈,遇到操作数就入栈,遇到操作符就连续取两个栈顶元素(先取出来的是右操作数),运算的结果再继续入栈(因为前一个操作符的两个操作数的运算结果是下一个操作符的操作数)。补充:一些操作符的操作数顺序不能颠倒,例如-和/,而有些可以颠倒,例如+和×。
最后一个操作符运算结束后,结果还是要入栈,即后缀表达式的运算结果就是在栈里面。
栈中的数据类型是int是为了方便运算:
stack<int> st;
若是string类里的字符类型反而不好运算,但是可以将string类转换成int,如何转换?——stoi
当前阶段不好区分操作符与操作数,需要自己手动判断区分。等到学到容器map和set就好区分了。
只有整型(char也可以,因为char也是一种整型)才能作为switch的条件以及case的语句,像string类是不能作为switch case的条件的。
因为运算符只有加减乘除四种,所以可以强行比较。
四、编写代码
class Solution {
public:int evalRPN(vector<string>& tokens) {stack<int> st;for (const auto& str : tokens){if (str == "+" || str == "-" || str == "*" || str == "/"){// 取操作数int right = st.top();st.pop();int left = st.top();st.pop();// 计算出结果再入栈switch(str[0]){case '+':st.push(left + right);break;case '-':st.push(left - right);break;case '*':st.push(left * right);break;case '/':st.push(left / right);break;}}else st.push(stoi(str));}return st.top();}
};