目录
前面介绍了中缀表达式转化为后缀表达式,那么后缀表达式怎么求值的呢?
一、算法原理
与中缀转化为后缀的问题不同,在对后缀表达式从左到右扫描的过程中,由于操作符在操作数的后面,所以要暂存操作数,碰到操作符的时候,再把暂存的两个操作数取出来,进行实际的计算。
仍然是栈的特性:操作符之作用于与它最近的两个操作数。
如“456*+”:
- 先扫描到4和5两个操作数,但是此时不知道这两个操作数要进行什么样的操作,所以暂存起来。
- 继续扫描,碰到了操作数6,还是不知道怎么计算,仍然暂存。
- 直到“*”,现在知道是栈顶的两个操作数5和6做乘法。计算结果是30。
- 注意:先弹出的是右操作数,后弹出的是左操作数,这一点对减法和除法比较重要。
- 为了继续后续的操作,我们把中间结果30压入栈顶,继续扫描。
- 当所有的操作符都处理完毕,栈中只留下一个操作数,就是表达式的值。
二、实例
三、流程
- 创建空栈operandstack用来存放操作数,把后缀表达式解析为单词
- 从左到右扫描列表:
- 如果单词是操作数,将单词转化为int,压入栈顶
- 如果单词是操作符,就开始求值,从栈顶弹出两个操作数,先弹出的是右操作数,后弹出的是左操作数,计算完成后将计算结果压入栈顶。
- 扫描结束后,表达式的值就在栈顶。
- 弹出栈顶的值,返回
四、代码
class Stack():
"""定义一个栈"""
def __init__(self):
self.items = []
def isEmpty(self):
return self.items() == []
def pop(self):
return self.items.pop()
def push(self, item):
return self.items.append(item)
def peek(self):
return self.items[len(self.items)-1]
def size(self):
return len(self.items)
def postfixEval(postfixExpr):
# 主函数
operandstack = Stack()
tokenlist = postfixExpr.split()
for token in tokenlist:
if token in '0123456789':
token = int(token)
operandstack.push(token)
else:
op2 = operandstack.pop()
op1 = operandstack.pop()
result = docal(op1, op2, token)
operandstack.push(result)
return operandstack.pop()
def docal(op1, op2, token):
if token == '+':
return op1 + op2
elif token == '-':
return op1 - op2
elif token == '*':
return op1 * op2
else:
return op1 / op2
print(postfixEval('456*+'))