# 从左到右遍历中缀表达式中的每个数字和符号,若是数字就输出,即成为后缀表达式的一部分;若是符号则要分为两种情况: # (1)是括号时,如果是左括号,直接将左括号入栈,如果是右括号则栈顶元素依次出栈并输出,直到有一个左括号出栈(出栈的左括号不输出到后缀表达式)。 # (2)是运算符号时,如果栈顶符号为左括号,则直接将这个运算符号入栈。栈顶符号不为左括号时,如果该运算符号优先级比栈顶运算符号高则入栈,比栈顶符号 # 低或者相等时则栈顶元素依次出栈并输出直到栈为空或者栈顶为左括号为止,然后将这个符号入栈。 # 最后将栈顶符号依次出栈并输出,得到的结果即为最终的后缀表达式。 # 转为后缀表达式,重在理解数字的顺序是怎样放的,符号的优先级如何确定,在后缀表达式确立好后,运算的顺序就确定
中缀表达式:列如exp="1+2*(4+12)",从左到右,先乘除,后加减
后缀表达式:运算符放在运算数后面,列如postexp[1,2,4,12,"+","*","+"]
def change_opt(opt):
result = [] #后缀表达式,前半部分是数字,后半部分是符号
stack = [] # 栈,最初存放符号,之后转接到result列表后面
item_lists = opt.split(' ')#运算表达式元素之间用空格隔开:
for item in item_lists:
# 如果当前字符为整数或者小数那么直接放入结果列表
if item.isdigit() or '.' in item: #S.isdigit()返回的是布尔值:True FalseS中至少有一个字符且如果S中的所有字符都是数字,
# 那么返回结果就是True;否则,就返回False,接受字符串
result.append(item)
else:
if len(stack) == 0: # 如果栈空,直接入栈
stack.append(item)
elif item in '*/(': # 如果当前字符为*/(,直接入栈
stack.append(item)
elif item == ')':
t = stack.pop()
while t != '(':
result.append(t)
t = stack.pop()
elif item in '+-' and stack[-1] in '*/':
if stack.count('(') == 0:
while stack:
result.append(stack.pop())
else: # 如果有左括号,输出到左括号为止
t = stack.pop()
while t != '(':
result.append(t)
t = stack.pop()
stack.append('(')
stack.append(item)
else:
stack.append(item)
#把栈中数据弹出
while stack:
result.append(stack.pop())
return result
# 从左到右遍历表达式的每个数字和符号,遇到的是数字就进栈,遇到的时符号就将栈顶的两个数字出栈进行计算,然后将计算结果入栈,最终栈里的值即为计算的结果。
#后缀表达式计算
def get_value(follow): #这个follow就是后缀表达式
num = [] #用于存放数字,整体放进去
base_opt = ['+', '-', '*', '/']
for j in follow:
if j.isdigit() or '.' in j:
num.append(float(j))
if j in base_opt: #数字表里数字越靠后,运算优先级越高,碰到一个运算符,弹出末尾两个计算得结果再放到栈顶,继续重复弹二
# 放一个的操作,直到遍历结束,栈顶剩一个结果
num2 = num.pop()
num1 = num.pop()
res=method(num1,num2,j) #计算
num.append(res)
return num[0]
def method(num1,num2,j):
if j == "+":
res=num1 + num2
elif j == "-":
res=num1 - num2
elif j == "*":
res=num1 * num2
else:
res=num1 / num2
return res
if __name__ == '__main__':
#空格隔开,括号注意中英文和顺序要乱
opt = "9 + ( 3 - 1 ) * 3 + 10 / 2"
result=change_opt(opt)
print(get_value(result))