Python 栈 四则运算
首先了解一下栈:
栈是限定仅在表尾进行插入和删除操作的线性表。允许插入与删除的一段叫做栈顶,另一端
叫做栈底,不含任何数据元素的栈称为空栈。栈又称为后进先出(Last In First Out)的线性
表,简称LIFO结构。
在Python中,可以用列表来实现栈:
lt = [3]
#相当于压栈
lt.append(4)
print(lt)
>>>[3,4]
#相当于弹栈
lt.pop()
print(lt)
>>>[3]
利用栈这种数据结构我们可以实现四则运算。首先,我们来了解一些名词:
中缀表达式:我们再平常写的四则运算表达式就叫做中缀表达式,运算符位于数字中间,例如:
9+3*(2+1)
后缀表达式:将运算符写到数字后面的式子叫做后缀表达式,对于上面的例子来说:
中缀表达式转为后缀表达式思路9+3*(2+1):
- 设立一个运算符栈和后缀表达式栈;
- 第一个元素为数字9,加入后缀表达式栈:9;
- 第二个元素为运算符“ + ”,加入到运算符栈:+;
- 第三个元素为数字3,后缀表达式栈:9 3;
- 第四个元素为运算符“ * ”,由于 “ * ” 的优先级大于栈顶元素 +,所以将其加入到运算符栈中:+ *;
- 第五个元素为“ ( ”,加入到运算符栈中:+ * (;
- 第六个元素为数字2,后缀表达式栈:9 3 2;
- 第七个元素为运算符“ + ”,加入到运算符栈:+ * ( +;
- 第八个元素为数字1,后缀表达式栈:9 3 2 1;
- 第九个元素为“ ) ”,并且由于这是最后一个元素,运算符栈开始弹出,并
加入到后缀表达式栈中:9 3 2 1 + * +
后缀表达式写出来后,又该怎样去计算呢?我们可以发现,当遍历后缀表达式时,可以将数字元素加入到一个新栈,然后遇到一个运算符就弹出两个数字进行运算,将值压栈,直到最后一个元素为止,这样新栈中的值就是运算结果.
代码:
# 转为后缀表达式.运算表达式元素之间用空格隔开:
def change_houzhui(s):
result = [] # 结果列表
stack = [] # 栈
s_lt = s.split(' ')
for item in s_lt:
if item.isnumeric(): # 如果当前字符为数字那么直接放入结果列表
result.append(item)
else: # 如果当前字符为一切其他操作符
if len(stack) == 0: # 如果栈空,直接入栈
stack.append(item)
elif item in '*/(': # 如果当前字符为*/(,直接入栈
stack.append(item)
elif item == ')': # 如果右括号则全部弹出(碰到左括号停止)
t = stack.pop()
while t != '(':
result.append(t)
t = stack.pop()
# 如果当前字符为加减且栈顶为乘除,则开始弹出
elif item in '+-' and stack[-1] in '*/':
if stack.count('(') == 0: # 如果没有左括号,弹出所有
while stack:
result.append(stack.pop())
else: # 如果有左括号,弹到左括号为止
t = stack.pop()
while t != '(':
result.append(t)
t = stack.pop()
stack.append('(')
stack.append(item) # 弹出操作完成后将‘+-’入栈
else:
stack.append(item) # 其余情况直接入栈(如当前字符为+,栈顶为+-)
# 表达式遍历完了,但是栈中还有操作符不满足弹出条件,把栈中的东西全部弹出
while stack:
result.append(stack.pop())
# 返回字符串
return result
#后缀表达式进行计算
def calac_houzhui(follow):
num = []
base_opt = ['+', '-', '*', '/']
for j in follow:
if j.isdigit():
num.append(int(j))
if j in base_opt:
num2 = num.pop()
num1 = num.pop()
if j == "+":
num.append(num1 + num2)
elif j == "-":
num.append(num1 - num2)
elif j == "*":
num.append(num1 * num2)
else:
num.append(num1 / num2)
return num
if __name__ == '__main__':
s = "9 + 3 * ( 2 + 1 )" #空格隔开,括号注意中英文不要乱
print(calac_houzhui(change_houzhui(s)))
>>>[18]