Python 借助逆波兰表达式(后缀表达式)实现简单计算器
0. 参考资料
1. 中缀表达式转后缀表达式
中缀表达式转后缀表达式的过程中需要两个主要存储结构。
- 用于存放最终后缀表达式的列表
postfix
- 用于存放运算符的栈
operators
,可以使用Python
中的列表实现
转换步骤:
- 从左到右顺序扫描中缀表达式
- 如果扫描到操作数,直接追加到后缀表达式
postfix
中 - 如果扫描到运算符:
(
左括号:
直接压栈到运算符栈operators
)
右括号:
依次弹出运算符栈中的元素,并放入到后缀表达式postfix
中;
直到遇到(
左括号,把它弹出后丢弃,后缀表达式中不需要括号。- 加减乘除:
如果该运算符优先级高于栈顶元素,则将它压栈到operators
;
如果该运算符优先级低于栈顶元素,依次弹出栈顶元素并把它们存入到后缀表达式postfix
中,直到遇到(
左括号或者优先级低于该运算符的栈顶元素时,保持栈顶元素不变,并将该运算符压栈到operators
。
- 扫描完毕中缀表达式后,将运算符栈
operators
中的其余元素依次弹出并追加到后缀表达式列表中。
2. 后缀表达式的求值
后缀表达式的求值过程中需要一个操作数栈 operands
来存储中间结果,可以用 Python
的列表来实现。
求值步骤如下:
- 从左到右扫描后缀表达式
- 如果是操作数,将操作数压栈
- 如果是运算符,弹出两个操作数进行运算(注意顺序,先弹出是右操作数,后弹出的是左操作数)
- 将运算结果压栈
- 将后缀表达式扫描完毕
- 最后操作数栈
operands
就剩一个元素,该元素为后缀表达式的结果
3. Python 代码实现
# 运算符元组
OPERATORS = ('+', '-', '*', '/', '(', ')')
# 优先级字典
PRIORITY = dict([
('+', 1),
('-', 1),
('*', 2),
('/', 2