根据逆波兰表示法,求表达式的值。
有效的运算符包括+,-,*,/
。每个运算对象可以是整数,也可以是另一个逆波兰表达式。
说明:
整数除法只保留整数部分。 给定逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。
示例 1:
输入: ["2", "1", "+", "3", "*"]
输出: 9
解释: ((2 + 1) * 3) = 9
示例 2:
输入: ["4", "13", "5", "/", "+"]
输出: 6
解释: (4 + (13 / 5)) = 6
示例 3:
输入: ["10", "6", "9", "3", "+", "-11", "*", "/", "*", "17", "+", "5", "+"]
输出: 22
解释:
((10 * (6 / ((9 + 3) * -11))) + 17) + 5
= ((10 * (6 / (12 * -11))) + 17) + 5
= ((10 * (6 / -132)) + 17) + 5
= ((10 * 0) + 17) + 5
= (0 + 17) + 5
= 17 + 5
= 22
概念
有几个概念大家需要理解。
1、操作数(数字)2、运算符(顾名思义)3、分界符(括号)注意,没必要去跟中括号较劲
中括号也拿小括号来算(当然他题目不一定出的有中括号)
好,理解完这个概念我们需要理解一个叫做后缀表达式的东西。
我们在试卷上看到的计算题那个格式就是中缀表达式,人可以判断先算哪里再算哪里有智能判断。但是机器不行,机器最方便的只能顺着来,跟着特定的规律来进行计算,所以,我们需要引入一个有顺序的东西叫做后缀表达式。
举个栗子:
一个算式:
6*(3+5)/8 = 6;
这是中缀表达式。3 5 + 6 * 8 /
最终等于6;这是后缀表达式。
在中缀表达式中,我们可以看到我们需要先算 3+5,而在后缀表达式中,3 5放在最前,运算符放后。以此类推,这就是后缀表达式。前缀表达式你们自己可以去看看,跟后缀表达式差不多。
思路
因为他输入进来的是一个一个字符串,所以我们要把字符串转成数字 字符串有可能不完全是操作数,也有可能是运算符(这里没有分界符)
弄一个结果栈stack,用来存放运算过程及结果,最终stack有且只有一个元素,那就是最终答案。
遍历输入的数组 如果是数字,则直接push到stack中,如果是+,-,*,/
,那说明是运算符,那我就把stack的上面两个元素出栈,并赋值给num1
num2,再把他们抛给计算函数,
注意,如果是减法和除法那得反过来,stack 入栈出栈顺序是相反的!
我们要把算出来的结果再压回给stack栈,方便下一次遇到运算符运算。
以此类推,最终stack.top()就是最终结果!
func evalRPN(_ tokens: [String]) -> Int {
var stack: Array<Int> = []
for string in tokens {
if "+-*/".contains(where: { String($0) == string }) {
let left = stack.last!
stack.removeLast()
let right = stack.last!
stack.removeLast()
var temp = 0
switch string {
case "+": temp = right + left
case "-": temp = right - left
case "*": temp = right * left
case "/": temp = right / left
default: break
}
stack.append(temp)
}
else {
stack.append(Int(string)!)
}
}
return stack.first!
}