1.题目描述
根据 逆波兰表示法,求表达式的值。有效的算符包括 +、-、*、/ 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。
注意 两个整数之间的除法只保留整数部分。
可以保证给定的逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。
示例1:
输入:tokens = [“2”,“1”,“+”,“3”,“*”]
输出:9
解释:该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9
示例2:
输入:tokens = [“4”,“13”,“5”,“/”,“+”]
输出:6
解释:该算式转化为常见的中缀算术表达式为:(4 + (13 / 5)) = 6
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/evaluate-reverse-polish-notation
2.题目分析
2.1 后缀表达式
这道题目其实就是一个后缀表达式求值问题,相比于中缀表达式转换为后缀表达式,单纯的求解后缀表达式的值是比较简单的。我们所说的中缀表达式就是日常见到的一般表达式,如a+b*c,13+89/(6+3)
此类。后缀表达式就是利用特殊的规则转化之后,消去表达式的括号,使得计算机可以使用栈来进行表达式求解。
这里我们复习一下中缀表达式转换为后缀表达式的规则,按照我们的思维来讲,就是在原来中缀表达式的基础上,按照运算优先级加括号,然后将运算符移到对应的括号后面。对于后缀二字,其实就是将运算符放到后面。下面就是对表达式1:4+13/5
的转化示例。
下面来一个复杂点的例子,将表达式(10 * (6 / ((9 + 3) * 11))) + 17
转化为后缀表达式:
2.2 后缀表达式求值
前面我们已经看到了中缀表达式转为后缀表达式。既然我们说到转化为后缀表达式是将云仿佛放到需要进行运算的数字的后面,那么对于它的运算我们就可以通过逐个读取来进行计算了。我们需要记住的规则是,对于一个后缀表达式当我们遍历到一个运算符的话,那么前面遍历到的两个数字必然是与这个运算符相关联的需要进行此运算的数。以公式1:[4,13,5,/,+]
为例我们有如下计算规则。
- 按顺序遍历,碰到
4,13,5
均为数字,所以逐个按序保存 - 遍历到运算符
/
,此时距离最近的两个数字应该按照此运算符参与运算,按顺序进行13/5=2; 以新计算的值替换刚刚参与计算的两个数 - 遍历到运算符
+
,取出最近的两个数4,2进行4+2,算出结果为6
经过上面的步骤我们应该已经对后缀表达式的求值有了一定的了解,按照其求解规律,一般选择栈来保存处理过程的数字,因为栈的后进先出特点与后缀表达式求值过程十分契合。
3.题目解答
3.1 使用条件判断选择运算符
class Solution {
public:
int evalRPN(vector<string>& tokens