表达式求值
前缀表达式: \(-*+ABC*-DE+FG\)
中缀表示式:\((((A+B)*C)-((D-E)*(F+G)))\)
后缀表达式:\(AB+C*DE-FG+*-\)
1 前缀表达式求解
操作符直接放入栈,遇到数字就弹出数字和符号进行计算,把计算的结果再放入栈
def pre_value(s):
s = s.split()
operate_stack = []
for token in s:
if token in "+/*-":
operate_stack.append(token)
else:
if operate_stack[-1] in "+-*/":
operate_stack.append(token)
else:
while len(operate_stack)>1 and operate_stack[-1] not in "+-*/":
num = operate_stack.pop()
operate = operate_stack.pop()
if operate=="+":
token = float(num) + float(token)
elif operate=="-":
token = float(num)-float(token)
elif operate=="*":
token = float(num)*float(token)
elif operate=="/":
token = float(num)/float(token)
operate_stack.append(str(token))
return operate_stack.pop()
print(pre_value('/ + 7 8 + 3 2'))
print(pre_value('+ * 7 8 * 3 2'))
print(pre_value('- * + 7 8 3 * - 2 9 + 1 5'))
print(pre_value('- * + 7 * 8 3 3 * - 2 9 + 1 5'))
2 后缀表达式求值
让数字进栈,遇见操作符之后弹出两个数字进行运算后,将数字放入栈
def end_value(s):
s = s.split()
stack = []
for token in s:
if token.isdigit():
stack.append(token)
else:
num2 = stack.pop()
num1 = stack.pop()
if token=="+":
stack.append(str(float(num1)+float(num2)))
elif token == "-":
stack.append(str(float(num1)-float(num2)))
elif token=="*":
stack.append(str(float(num1)*float(num2)))
else:
stack.append(str(float(num1)/float(num2)))
return stack.pop()
print(end_value('7 8 + 3 2 + /'))
print(end_value("7 8 * 3 2 * +"))
print(end_value("7 8 + 3 * 2 9 - 1 5 + * -"))
print(end_value("7 8 3 * + 3 * 2 9 - 1 5 + * -"))
3 中缀表达式求值
中缀表达式一般都是转化成前缀表达式或者后缀表达式进行求解
3.1 中缀表达式转换成前缀表达式
从右到左(反转)遍历中缀表达式,遇到操作数(字母及数字),则输出;遇到")",则进栈;遇到"(",则弹出栈顶,若栈顶不为")“则输出,继续弹出下一个栈顶并比较,直到弹出”)",结束循环;遇到运算符,若栈不为空,且栈顶元素的优先级>=运算符的优先级(表明栈顶元素也是运算符,这2个运算符相邻),弹出并输出栈顶元素,继续循环比较,直到不符合循环条件,再将该运算符入栈;遍历结束后,若栈仍不为空,则依次弹出并输出,将最终输出连接并返回结果。
def mid2pre(s):
s = s.split()[::-1]
stack = []
res = []
for token in s:
if token==")":
stack.append(token)
elif token.isdigit() or token.isalpha():
res.append(token)
elif token=="(":
while stack and stack[-1]!=")":
res.append(stack.pop())
if stack:
stack.pop()
elif token in "+-*/":
if token in "+-":
while stack and stack[-1] in "+-*/":
res.append(stack.pop())
stack.append(token)
else:
while stack and stack[-1] in "*/":
res.append(stack.pop())
stack.append(token)
while stack:
res.append(stack.pop())
return "".join(res[::-1])
3.2 中缀表达式转换成后缀表达式
从左到右遍历中缀表达式,遇到操作数(字母及数字),则输出;遇到"(",则进栈;遇到")",则弹出栈顶,若栈顶不为"(“则输出,继续弹出下一个栈顶并比较,直到弹出”(",结束循环;遇到运算符,若栈不为空,且栈顶元素的优先级>=运算符的优先级(表明栈顶元素也是运算符,这2个运算符相邻),弹出并输出栈顶元素,继续循环比较,直到不符合循环条件,再将该运算符入栈;遍历结束后,若栈仍不为空,则依次弹出并输出,将最终输出连接并返回结果。
def mid2end(s):
s = s.split()
stack = []
res = []
for token in s:
if token.isdigit() or token.isalpha():
res.append(token)
elif token == "(":
stack.append(token)
elif token in "+-*/":
if token in "+-":
while stack and stack[-1] in "+-*/":
res.append(stack.pop())
stack.append(token)
else:
while stack and stack[-1] in "*/":
res.append(stack.pop())
stack.append(token)
elif token==")":
while stack and stack[-1]!="(":
res.append(stack.pop())
stack.pop()
while stack:
res.append(stack.pop())
return res
print(mid2end("A * B + C * D"))
print(mid2end("( A + B ) * C - ( D - E ) * ( F + G )"))
print(mid2end("( A + B * C ) * C - ( D - E ) * ( F + G )"))