📅  最后修改于: 2023-12-03 15:42:21.633000             🧑  作者: Mango
这是一道经典的编程题,也是门|门 IT 2006 的其中一道试题。本题要求程序员实现一个简单的计算器,支持加、减、乘、除四种基本的算术运算。以下是详细的要求和注意事项:
calc(str: str) -> float
,接收一个包含算术表达式的字符串 str
,返回运算结果。str
中可能包含的字符为数字、加号、减号、乘号、除号和空格,其中空格可以出现在表达式中的任何位置,但其它字符只能出现在数字之间。ValueError
,并给出相应的提示信息。本题的难点在于如何将一个包含算术表达式的字符串转化为运算结果。一种简单而有效的方法是将中缀表达式转化为后缀表达式,并使用栈来计算结果。
具体来说,可以使用一个操作数栈和一个操作符栈来实现转化和计算。遍历表达式中的每个字符,分别进行以下操作:
最后将操作符栈中剩余的操作符依次弹出并计算,直到操作符栈为空,操作数栈中只剩下一个元素,即为计算结果。
以下是本题的参考答案实现,具体细节可参见代码注释。该实现使用了 Python 语言,并采用了面向对象的编程方式,方便扩展和优化。
class Calculator:
def __init__(self):
self._ops = [] # 操作符栈
self._nums = [] # 操作数栈
def _push_op(self, op):
"""
将操作符压入操作符栈
"""
# 如果当前操作符优先级比栈顶操作符高,则直接压入
if not self._ops or op == '(' or self._ops[-1] == '(' or self._priority(op) > self._priority(self._ops[-1]):
self._ops.append(op)
else:
# 否则将栈顶操作符弹出并计算,并循环进行直到满足条件
while self._ops and self._ops[-1] != '(' and self._priority(op) <= self._priority(self._ops[-1]):
self._calc()
self._ops.append(op)
def _push_num(self, num):
"""
将操作数压入操作数栈
"""
self._nums.append(float(num))
def _priority(self, op):
"""
获取操作符优先级
"""
if op == '+' or op == '-':
return 1
elif op == '*' or op == '/':
return 2
else:
return 0
def _calc(self):
"""
计算栈顶操作符的结果,并将结果压入操作数栈
"""
if len(self._nums) < 2 or not self._ops:
raise ValueError('Invalid expression!')
b = self._nums.pop()
a = self._nums.pop()
op = self._ops.pop()
if op == '+':
self._nums.append(a + b)
elif op == '-':
self._nums.append(a - b)
elif op == '*':
self._nums.append(a * b)
elif op == '/':
if b == 0:
raise ValueError('Division by zero!')
self._nums.append(a / b)
else:
raise ValueError('Invalid operator!')
def calc(self, expr):
"""
计算表达式结果
"""
for i in range(len(expr)):
if expr[i].isspace():
continue
elif expr[i].isdigit():
# 如果是数字,则读取直到下一个字符不是数字或者到达字符串末尾
j = i + 1
while j < len(expr) and expr[j].isdigit():
j += 1
num = expr[i:j]
self._push_num(num)
i = j - 1
elif expr[i] in '+-*/':
self._push_op(expr[i])
elif expr[i] == '(':
self._ops.append(expr[i])
elif expr[i] == ')':
while self._ops and self._ops[-1] != '(':
self._calc()
if not self._ops:
raise ValueError('Invalid expression!')
self._ops.pop()
else:
raise ValueError('Invalid expression!')
while self._ops:
self._calc()
# 如果操作数栈中元素不止一个,则表达式错误
if len(self._nums) != 1:
raise ValueError('Invalid expression!')
return self._nums[0]
以下是一个简单的测试代码,展示了如何使用 Calculator
类计算一个表达式的结果:
if __name__ == '__main__':
calc = Calculator()
expr = '1 + (2 - 3) * 4 / 5'
try:
result = calc.calc(expr)
print(f'{expr} = {result:.2f}')
except ValueError as e:
print(f'Error: {e}')
输出结果为:1 + (2 - 3) * 4 / 5 = 0.40
。