力扣227:基本计算器II
题目描述
:
给定有效字符串s,实现基本计算器来计算并返回其值?其中除法仅保留整数部分。
Example Input
s = " 3-5 / 2 "
Output
1
官方题解的思路比较简单,通俗来讲就是在每个表达式前加一个符号“+”
,然后根据每个数字的前置符号位计算结果,如果是"+"
或者"-"
,则直接添加,如果是乘除
则从栈
中pop
末尾,实现优先运算。
举例说明
:
s = " 3-5 / 2 "
,首先去除空格,可以另起一个新循环进行预处理,也可以直接在主循环中操作(当前字符是空格时直接跳过,进入下一轮循环)。处理后s="3-5/2"
,在表达式前加一个符号“+”
,s="+3-5/2"
,开始遍历:
+
: 置前置符号位为+
;stack=[]
3
: 前置符号位为+
,栈中放入+3
;stack=[+3]
-
: 置前置符号位为-
;stack=[+3]
5
: 前置符号位为-
,栈中放入-5
;stack=[+3,-5]
/
: 置前置符号位为/
;stack=[+3,-5]
2
: 前置符号位为/
,弹出栈尾,计算-5/2
,入栈stack=[+3,-5/2]
- 求栈中所有元素之和:
1
。
数据结构中,栈往往还被应用于中序
转后序
。再根据后序栈
直接计算表达式结果。
中序遍历序列:3-5/2
后序遍历序列:352/-
根据计算规则,建立一个新的空栈stack_new
,遍历后序序列,若为数字则进栈,若为操作符则依次弹出两个元素计算后,再次入栈。
3
: 入栈;stack_new=[3]
5
: 入栈;stack_new=[3,5]
2
: 入栈;stack_new=[3,5,2]
/
: 操作符,出栈两元素:5/2
,计算后入栈;stack_new=[3,2]
-
: 操作符,出栈两元素:3-2
,计算后入栈;stack_new=[1]
# 明天更新代码注释---2021.3.12
priority_matrix = [[0,1,5,5,3,3,6],[0,6,4,4,2,2,1]]
isp_operator = ['#','(','*','/','+','-',')']
icp_operator = ['#','(','*','/','+','-',')']
优先级比较表格:
# | ( | *, / | +, - | ) | |
---|---|---|---|---|---|
isp | 0 | 1 | 5 | 3 | 6 |
icp | 0 | 6 | 4 | 2 | 1 |
isp
表示栈内、icp
表示栈外,操作符的优先级用于判定对当前字符的操作。
# 实现中序序列向后序序列的转换
snew = list(s.replace(" ",""))
s = []
s.extend(snew)
s.append('#')
lens = len(s)
index = 0
stack = ['#'] # 辅助栈
output = [] # 存储后序序列的栈
while index < lens:
# 读取的是数字,则直接输出至后序序列栈
if s[index] not in isp_operator:
num = 0
while s[index] not in isp_operator:
num = num * 10 + int(s[index])
index += 1
output.append(num)
# 读取的是非数值,比较栈内与当前操作符的优先级
else:
cicp = priority_matrix[1][icp_operator.index(s[index])]
cisp = priority_matrix[0][isp_operator.index(stack[-1])]
if cisp == cicp:
stack.pop()
index += 1
elif cisp < cicp:
stack.append(s[index])
index += 1
else:
tmp = stack.pop()
output.append(tmp)
# 依据后序序列计算表达式的数值
res = 0
stack = [] # 存储结果的栈
for i in output:
if i in isp_operator:
b = int(stack.pop())
a = int(stack.pop())
if i == isp_operator[2]:
stack.append(a*b)
elif i == isp_operator[3]:
stack.append(int(a/b))
elif i == isp_operator[4]:
stack.append(a+b)
else:
stack.append(a-b)
else:
stack.append(int(i))
return stack[-1]