class Stack:
"""Stack implementation using a list"""
def __init__(self) -> None:
"""Create new stack"""
self._items: list = []
def is_empty(self) -> bool:
"""Check if the stack is empty"""
return not bool(self._items)
def push(self, item) -> None:
"""Add an item to the stack"""
self._items.append(item)
def pop(self):
"""Remove an item from the stack"""
return self._items.pop()
def peek(self):
"""Get the value of the top item in the stack"""
return self._items[-1]
def size(self) -> int:
"""Get the number of items in the stack"""
return len(self._items)
operator = { #前后顺序代表优先级
'*': lambda a, b: a * b,
'/': lambda a, b: a / b,
'+': lambda a, b: a + b,
'-': lambda a, b: a - b,
'||': lambda a, b: a or b,
'&&': lambda a, b: a and b,
'(': ValueError,
')':ValueError
}
priority = {}
x=2147483647
for i in list(operator):
x-=1
priority[i]=x
list_priority = list(priority)
def infix_to_postfix(infix: (str, list)) -> list:
"""将中序表达式转化为后序表达式,核心思想"""
if type(infix) == str:
for c in list_priority:
infix = infix.replace(c, " {} ".format(c))
while infix.find(" ") != -1:
infix = infix.replace(" ", " ")
in_list = infix.split() # 将字符串变为列表,注意,输入时需要空格隔开单个元素,例:"1 2 3 * 2 3"
else:
in_list = infix
stack1 = Stack() # 创建空栈,用于存储遍历字符串列表的括号、操作符
post_list = [] # 创建空列表,用于存储后序表达式
for elem in in_list: # 遍历中序表达式
if elem == '(': # 为左括号,入栈
stack1.push(elem)
elif elem == ')': # 为右括号,则出栈,添加到输出列表,直到匹配到左括号
token = stack1.pop()
while token != '(':
post_list.append(token)
token = stack1.pop()
elif elem in list_priority: # 为操作符,则判断栈中是否有更高优先级的操作符,有则出栈,无则添加到列表尾部,
while (not stack1.is_empty()) and (priority[stack1.peek()] >= priority[elem]):
post_list.append(stack1.pop())
stack1.push(elem) # 若放到列表尾部,则栈永远不会有操作符
else:
post_list.append(elem)
while not stack1.is_empty(): # 若栈不为空,则弹出到后续表达式列表(即优先级低的放最后)
post_list.append(stack1.pop())
return post_list
def is_number(s: str) -> bool:
try:
s = float(s)
return True
except:
return False
def calculation_postfix(postfix: (list, str)) -> float:
if type(postfix) == str:
postfix = postfix.split(" ")
number_stack = Stack()
while len(postfix) != 0:
s = postfix[0]
del postfix[0]
if s in list_priority:
number_stack.push(operator[s](b=number_stack.pop(), a=number_stack.pop()))
elif is_number(s):
number_stack.push(float(s))
else:
raise TypeError
return number_stack.pop()
def calculation_infix(infix: (list, str)) -> float:
return calculation_postfix(infix_to_postfix(infix))
while True:
infix = input("infix:")
print("result:{}\n".format(calculation_infix(infix)))
————————————————
本文infix_to_postfix函数借鉴了CSDN博主「Cathedrals」的原创文章,遵循CC4.0 BY - SA版权协议
Cathedrals文章链接:https: // blog.csdn.net / jluzhanghm1720 / article / details / 120604994