需求
需求:中缀表达式 转 后缀表达式(前缀表达式)
输入:中缀表达式
输出:后缀表达式
算法思路
从左到右扫描中缀表达式单词列表
- 如果单词是操作数,则直接添加到后缀表达式列表的
末尾 - 如果单词是左括号“(”,则压入opstack栈顶
- 如果单词是右括号“)”,则反复弹出opstack栈顶操作符,加入到输出列表末尾,直到碰到左括号
- 如果单词是操作符“*/±”,则压入opstack栈顶
• 但在压入之前,要比较其与栈顶操作符的优先级
• 如果栈顶的高于或等于它,就要反复弹出栈顶操作符,加入到输出列表末尾
• 直到栈顶的操作符优先级低于它
代码实现
我们会用栈来暂存未操作的操作符
class Stack(object):
"""栈"""
def __init__(self):
self.items = []
def is_empty(self):
return self.items == []
def push(self, item):
self.items.append(item)
def pop(self):
return self.items.pop()
def peek(self):
# 窥视:查看栈顶的元素
return self.items[len(self.items) - 1]
def size(self):
return len(self.items)
中缀表达式 转 后缀表达式
from test05_stack.Stack import Stack
def middle_to_after(expr):
# 记录操作符优先级
expr_list = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
opt_dict = dict()
opt_dict["("] = 1
opt_dict["+"] = 2
opt_dict["-"] = 2
opt_dict["*"] = 3
opt_dict["/"] = 3
# 初始化栈数据结构,用来保存暂未处理的操作符
sk = Stack()
# 创建一个保存表达是的列表
opt_list = list()
# 转换操作
for item in expr.split():
# 如果该字符是 字符,直接输出到opt_list中
if item in expr_list:
opt_list.append(item)
# 如果该 字符 是 “(”,直接进行压栈操作
elif item == "(":
sk.push(item)
# 如果是 “)”,则弹出栈中所有的操作符,并添加到opt_list,直到遇到 “(”
elif item == ")" and not sk.is_empty():
pop_str = sk.peek()
while pop_str != "(":
opt_list.append(sk.pop())
pop_str = sk.pop()
# 如果是 “+-*/”,先比较该操作符和栈顶操作符的优先级,
elif item in "+-*/":
# 如果栈中没有操作符,直接压栈
if sk.is_empty():
sk.push(item)
# 如果大于栈顶的优先级,则直接压栈;
elif opt_dict[item] >= opt_dict[sk.peek()]:
sk.push(item)
# 否则要弹出栈中优先级比自己高的操作符
else:
while opt_dict[item] < opt_dict[sk.peek()]:
opt_list.append(sk.pop())
# 把操作符添加到opt_list中
while not sk.is_empty():
opt_list.append(sk.pop())
# 遍历输出opt_list中的内容
ret = "".join([str(i) for i in opt_list])
return ret
# 测试
print(middle_to_after("A + B * C"))
print(middle_to_after("( A + B ) * C"))
# 测试结果
ABC*+
AB+C*