字符串表达式求值对于python而言,有一个很方便的方法:eval(),可以直接求出得到结果,这里我想利用python手写实现一个,即利用stack和中缀表达式转后缀表达式方法来求
中缀表达式转后缀表达式发现这个方法的人真是个人才…后缀表达式又叫逆波兰式(Reverse Polish notation),中缀转后缀思路也不麻烦,只要学过数据结构和算法的同学几乎都会学习这一块内容。转为后缀表达式的原因正是计算机是栈式结构这个原因,因此,理解到转换思路对于理解计算机系统结构也有一定帮助。
将一个普通的中缀表达式转换为后缀表达式的一般算法:
step1 初始分配2个空栈,一个符号栈s1,一个数字栈s2(数字栈会包含最终的后缀表达式结果,同时符号栈用于保存中间符号,最后也会成为一个空栈)。 step2 从中缀式的左端开始取字符,逐序进行如下步骤: step2.1 判断如果是字符(非数字) step2.1.1 如果s1为空,字符进s1 step2.1.2 如果s1不为空,继续判断 step2.1.2.1 如果是"(",直接压进s1 step2.1.2.2 如果是")",迭代弹出s1栈顶元素,直到遇到"(",然后弹出将其弹出 step2.1.2.3 否则,需要将优先级大于该元素的栈顶元素,一一弹出到数字栈s2中,然后将其压进符号栈s1,直到遇到"("或者为空 step2.2 如果不是符号,将数字直接压进数字栈s2有点像编译原理里的自动机…
下面是核心代码
# 中缀表达式转为后缀表达式
# 输入:字符串中缀表达式
# 输出:后缀表达式
def TranHou(str):
Pri = {'(': 3, '*': 2, '/': 2, '+': 1, '-': 1, ')': 0}#制定优先级
st_num = Stack()#数字栈
st_symbol = Stack()#符号栈
lens = len(str)
for i in range(lens):
if str_j(str[i]): # 2.1 如果是符号
if st_symbol.isEmpty() : # 2.1.1如果为空,直接入栈
st_symbol.push(str[i])
else: # 2.1.2不为空
if str[i] == "(":st_symbol.push(str[i]) # 2.1.2.1如果是"(",直接压进去
elif str[i] == ")": # 2.1.2.2如果是")",迭代弹出栈顶元素,直到遇到"(",然后弹出将其弹出
while (st_symbol.top() != "("):
st_num.push(st_symbol.pop())
st_symbol.pop()
else: # 2.1.2.3否则,需要将优先级大于该元素的栈顶元素,一一弹出到数字栈中,然后将其压进符号栈,直到遇到"("或者为空
while(Pri[st_symbol.top()] >= Pri[str[i]]):
if st_symbol.top()=='(':
break
st_num.push(st_symbol.pop())
if st_symbol.isEmpty():break
st_symbol.push(str[i])
else:st_num.push(str[i]) # 2.2如果不是符号,数字直接压进数字栈
st_num.push(st_symbol.pop()) # 把最后一个符号也压入数字栈
return st_num
后缀表达式的计算
得到后缀表达式后计算就比较简单了,可以把后缀表达式利用两个栈,或者其它数据结构(队列等),依次取出字符,如果取得的字符是非数字的,就把前两个取出的数字和这个符号进行±*/数值计算,然后再压进去,有图展示就方便了,这里就不画了,直接看人家的,链接如下:
https://www.cnblogs.com/lanhaicode/p/10776166.html
完整代码见:github