1.先创建SqStack类,用于操作顺序栈
class SqStack:
# 构造函数
def __init__(self):
self.data = [] # 声明空列表,作为栈的存放元素
# 判断栈是否为空
def empty(self):
if len(self.data) == 0:
return True
return False
# 进栈
def push(self, item):
self.data.append(item)
# 出栈
def pop(self):
assert not self.empty() # 判断栈是否为为空
return self.data.pop() # pop() 函数用于移除列表中的一个元素(默认最后一个元素),并且返回该元素的值。
# 取栈顶元素
def get_top(self):
assert not self.empty()
return self.data[-1] # data[-1]取出倒数第一个数
2.创建ExpressClass类,用于获取中缀表达式转后缀表达式(逆波兰表达式),以及获取后缀表达式的值
- 创建init构造函数
- 创建get_post_exp函数,获取后缀表达式
- 创建trans函数,中缀表达式转后缀表达式
- 创建get_value,获取后缀表达式的值
from SqStack import SqStack
class ExpressClass:
def __init__(self, str):
self.exp = str # 中缀表达式存放位置
self.post_exp = [] # 后缀表达式存放位置
def get_post_exp(self): # 返回后缀表达式
return self.post_exp
def trans(self): # 中缀转后缀
opor = SqStack() # 创建空栈
i = 0 # 栈下标
while i < len(self.exp):
ch = self.exp[i] # 取出栈元素
if ch == "(": # 遇到左括号,入符号栈
opor.push(ch)
elif ch == ")": # 遇到右括号,需要取出符号栈元素,追加到后缀表达式栈中
while not opor.empty() and opor.get_top() != "(":
e = opor.pop() # 将"("之前的所有元素退栈,因为在栈中"("之前的意思是在"("后进去的元素,出来的时候在"("之前出
self.post_exp.append(e) # 把符号追加到后缀栈中
opor.pop() # 將“(”退栈
elif ch == "+" or ch == "-": # 入符号栈
# 先取出符号栈的栈顶元素,判断是否是(,如果不是,则把符号栈的符号取出来入后缀表达式栈
while not opor.empty() and opor.get_top() != "(":
e = opor.pop()
self.post_exp.append(e)
# 如果符号栈是(,则直接入栈
opor.push(ch)
elif ch == "*" or ch == "/": # 入符号栈
while not opor.empty():
e = opor.get_top() # 获取栈顶元素
if e != "(" and (e == "*" or e == "/"):
e = opor.pop()
self.post_exp.append(e)
else:
break
opor.push(ch) # 把符号入栈
else: # 就是数字,入后缀表达式栈
d = "" # 保存数字
# 判断是否是数字
while "0" <= ch <= "9": # 判断是否为数字,如果是,则一直取出所有数字
d += ch
i += 1
if i < len(self.exp): # 如果当前项为最后一项,因为先加1,则会超出索引,所以要先判断,超出最后一项,则结束所有循环,也就是break
ch = self.exp[i] # 取出当前下标的元素
else:
break # 退出所有循环
i -= 1 # 循环完毕则退格,减1只适合最大2位数的数字运算
self.post_exp.append(int(d)) # 后缀表达式入
i += 1
# 判断符号栈是否为空,没空,就把元素压入后缀栈中
while not opor.empty():
self.post_exp.append(opor.pop())
# 获取后缀表达式的值
def get_value(self):
opand = SqStack() # 创建空栈 # 创建空栈
i = 0 # 栈的下标
while i < len(self.post_exp):
opv = self.post_exp[i] # 从头0取出栈中的元素
if opv == "+": # 如果遇到+
a, b = opand.pop(), opand.pop()
c = a + b
opand.push(c) # 计算结果再放入栈
elif opv == "-":
a, b = opand.pop(), opand.pop() # 此处先获取a,再获取b,入栈时,减数后入,出栈时减数先出,所以a是减数
c = b - a
opand.push(c) # 计算结果再放入栈
elif opv == "*":
a, b = opand.pop(), opand.pop()
c = a * b
opand.push(c) # 计算结果再放入栈
elif opv == "/":
a, b = opand.pop(), opand.pop() # 此处先获取a,再获取b,入栈时,分母后入,出栈时分母先出,所以a是分母
assert a != 0 # 分母不为0
c = b / a
opand.push(c) # 计算结果再放入栈
else:
opand.push(opv) # 如果不是符号,则直接入栈opand
i += 1
return opand.get_top() # 返回栈顶元素
3.最后创建main类
from ExpressClass import ExpressClass
if __name__ == '__main__':
ex = ExpressClass("(56-20)/(4+2)")
ex.trans()
print(ex.get_post_exp())
print(ex.get_value())
我们测试一下(56-20)/(4+2), 得如下图
扩展:无栈类实现
原理都是一样的,只是把栈类换成列表
# 未使用SqStack类
def get_value(str):
opand = [] # 创建空栈 # 创建空栈
i = 0 # 栈的下标
while i < len(str):
opv = str[i] # 从头0取出栈中的元素
if opv == "+": # 如果遇到+
a, b = opand.pop(), opand.pop()
c = int(a) + int(b)
opand.append(c) # 计算结果再放入栈
elif opv == "-":
a, b = opand.pop(), opand.pop() # 此处先获取a,再获取b,入栈时,减数后入,出栈时减数先出,所以a是减数
c = int(b) - int(a)
opand.append(c) # 计算结果再放入栈
elif opv == "*":
a, b = opand.pop(), opand.pop()
c = int(a) * int(b)
opand.append(c) # 计算结果再放入栈
elif opv == "/":
a, b = opand.pop(), opand.pop() # 此处先获取a,再获取b,入栈时,分母后入,出栈时分母先出,所以a是分母
assert a != 0 # 分母不为0
c = int(b) / int(a)
opand.append(c) # 计算结果再放入栈
else:
opand.append(opv) # 如果不是符号,则直接入栈opand
i += 1
return opand[-1] # 返回栈顶元素
if __name__ == '__main__':
ipt = input()
ipt = list(ipt.split())
re = get_value(ipt)
print(re)
测试案例:[56, 20, '-', 4, 2, '+', '/']