前面也说过,对于计算机来说(不仅仅是计算机)中缀表达式都是复杂的,它要考虑到优先级的问题,很伤脑筋,至于中缀向后缀的转换也是一个很伤脑筋的事情,在转换的过程中要考虑到很多优先级的情况。
好了,既然跟优先级有关,那么我们就应该为各个运算符号设置一个优先级,我们很明显对于加减乘除的优先级已经很明显能知道怎么设定,关键是扩号这个拥有最高优先级的符号该怎么设置优先级。在考虑这个问题之前我们首先考虑一下没有括号的中缀表达式怎么转换成后缀
首先,设置优先级:
priority = { "+": 3, "-": 3, "*": 5, "/": 5}
这是我们已知的最简单设置的优先级
考虑实现的话,我们建立一个栈用于存储运算符,列表用于存储慢慢形成的后缀表达式:
S = Stack()
exp = []
infix_operators = '+-*/'
分析一下中缀怎么转换成后缀,对于遇到数字,直接放在后缀表达式的表中就可以了。经过分析,我们应该清楚,每次想加入一个运算符到后缀表达式中时总是要比较一下它与它在中缀表达式后面的一个符号的优先级大小;如果他的优先级大于后面一个,直接将他加入到后缀表达式中,如果他的优先级小于后面一个,我们只有先将它压到栈中,在待它的下一个运算符加入到后缀表达式中后再讲它加入到后缀表达式中。
我想以上就是整个转换过程中的关键。
def trans_infix_suffix(line):
line = line.split(" ")
st = Stack()
# 这里栈用于处理运算符
exp = []
# 这里的列表用于保存后缀表达式
for i in line:
if i not in infix_operators:
exp.append(i)
# 遇到数字我们直接加进去就好
elif st.is_empty():
st.push(i)
# 如果栈是空的,那说明它还要比较下一个运算符的优先级
else:
while not st.is_empty():
if priority[i] > priority[st.top()]:
break
else:
exp.append(st.pop())
st.push(i)
# 关键在于每次放进去符号之前都要比较一下,它与下一个运算符的优先级大小
while not st.is_empty():
exp.append(st.pop())
return " ".join(exp)
上面就是转换一个没有括号的中缀,下面我们看一下包含括号的。
from 栈的顺序表实现 import Stack
priority = { "(": 1, "+": 3, "-": 3, "*": 5, "/": 5}
# 括号设置一个优先级比较低
infix_operators = "+-*/()"
def trans_infix_suffix(line):
line = line.split(" ")
st = Stack()
# 这里栈用于处理运算符
exp = []
# 这里的列表用于保存后缀表达式
for i in line:
if i not in infix_operators:
exp.append(i)
elif st.is_empty() or i == '(':
st.push(i)
# 遇到括号我们直接插入就行了
elif i == ")":
x = st.pop()
while x != '(':
exp.append(x)
x = st.pop()
else:
while not st.is_empty():
if priority[i] > priority[st.top()]:
break
else:
exp.append(st.pop())
st.push(i)
while not st.is_empty():
exp.append(st.pop())
return " ".join(exp)
中缀转换为后缀大概就是这样,其实里面的我也讲的不是很清楚,大概理解。