使用栈实现中缀表达式转为后缀表达式和后缀表达式的求解
书籍在线网址http://interactivepython.org/runestone/static/pythonds/index.html
中文翻译书籍:https://facert.gitbooks.io/python-data-structure-cn/
将中缀表达式转换为后缀表达式
中缀表达式(上图,一般书写)转换为后缀表达式(ABC*+)
方法:
- 创建一个名为 opstack 的空栈以保存运算符。给输出创建一个空列表。
- 通过使用字符串方法拆分将输入的中缀字符串转换为标记列表。
- 从左到右扫描标记列表。
- 如果标记是操作数,将其附加到输出列表的末尾。
- 如果标记是左括号,将其压到 opstack 上。
- 如果标记是右括号,则弹出 opstack,直到删除相应的左括号。将每个运算符附加到输出列表的末尾。
- 如果标记是运算符,
*,/,+
或-
,将其压入 opstack。但是,首先删除已经在 opstack 中具有更高或相等优先级的任何运算符,并将它们加到输出列表中。
- 当输入表达式被完全处理时,检查 opstack。仍然在栈上的任何运算符都可以删除并加到输出列表的末尾。
使用字典来保存操作符优先级,这个字典将每个运算符映射到一个整数,可以与其他运算符的优先级(我们使用整数3,2和1)进行比较。左括号将赋予最低的值。这样,与其进行比较的任何运算符将具有更高的优先级
1 #coding:utf8 2 from stack import Stack 3 def infixToPostfix(infixexpr): 4 prec = {} 5 prec["*"] = 3 6 prec["/"] = 3 7 prec["+"] = 2 8 prec["-"] = 2 9 prec["("] = 1 10 opStack = Stack() 11 postfixList = [] #创建后缀输出列表 12 tokenList = infixexpr.split() #将中缀列表转换为字符串 13 14 for token in tokenList: 15 #如果标记是操作数,将其附加到输出列表末尾 16 if token in "ABCDEFGHIJKLMNOPQRSTUVWXYZ" or token in "0123456789": 17 postfixList.append(token)
18 #如果标记是左括号,将其压栈 19 elif token == '(': 20 opStack.push(token)
21 #如果标记是右括号,弹栈添加到输出列表末尾直到遇到左括号 22 elif token == ')': 23 topToken = opStack.pop() 24 while topToken != '(': 25 postfixList.append(topToken) 26 topToken = opStack.pop()
27 #如果标记是运算符,删除已经在栈中具有更高或相等优先级的任何运算符并添加到输出列表末尾,再压栈 28 else: 29 while (not opStack.isEmpty()) and (prec[opStack.peek()] >= prec[token]): 30 postfixList.append(opStack.pop()) 31 opStack.push(token) 32 33 while not opStack.isEmpty(): #输入表达式完全处理后将栈中剩下内容添加到输出列表末尾 34 postfixList.append(opStack.pop()) 35 return " ".join(postfixList) #列表转字符串 36 37 print(infixToPostfix("A * B + C * D")) 38 print(infixToPostfix("( A + B ) * C - ( D - E ) * ( F + G )"))
#A B * C D * +
#A B + C * D E - F G + * -
后缀表达式求值
对后缀表达式4 5 6 * +求值
方法:
- 创建一个名为
operandStack
的空栈。 - 拆分字符串转换为标记列表。
- 从左到右扫描标记列表。
- 如果标记是操作数,将其从字符串转换为整数,并将值压到operandStack。
- 如果标记是运算符
*,/,+
或-
,它将需要两个操作数。弹出operandStack 两次。 第一个弹出的是第二个操作数,第二个弹出的是第一个操作数。执行算术运算后,将结果压到操作数栈中。
- 当输入的表达式被完全处理后,结果就在栈上,弹出 operandStack 并返回值。
1 from stack import Stack 2 def postfixEval(postfixExpr): 3 operandStack=Stack() 4 tokenList=postfixExpr.split() #根据空格分隔字符串返回列表 5 print(tokenList) 6 #['7', '8', '+', '3', '2', '+', '/'] 7 8 for token in tokenList: 9 if token in "0123456789": 10 operandStack.push(int(token)) 11 else: 12 operand2=operandStack.pop() 13 operand1=operandStack.pop() 14 result=doMath(token,operand1,operand2) 15 operandStack.push(result) 16 return operandStack.pop() 17 18 def doMath(op,op1,op2): 19 if op=="*": 20 return op1*op2 21 elif op=='/': 22 return op1/op2 23 elif op=="+": 24 return op1+op2 25 else: 26 return op1-op2 27 28 print(postfixEval('7 8 + 3 2 + /')) 29 30 #['7', '8', '+', '3', '2', '+', '/'] 31 #3.0