📅  最后修改于: 2023-12-03 15:42:14.131000             🧑  作者: Mango
给定一个将数值与函数符号组合而成的字符串,设计程序对其进行求值。
一个长度不超过100的字符串,其中包含任意个数的整数和以下函数符号:
+
:表示加法-
:表示减法*
:表示乘法/
:表示除法^
:表示指数运算%
:表示取模运算sqrt
:表示开方运算sin
:表示正弦函数cos
:表示余弦函数tan
:表示正切函数一个整数,为字符串表达式的求值结果。如果表达式非法,则输出 ERROR
。
25+3*4-1+sqrt(4)
42
该字符串表达式等价于 ((25 + (3 * 4)) - 1) + sqrt(4)
。
这是一道计算器表达式求值的题目,可以通过将表达式转换成后缀表达式来求值。
具体做法是,使用栈来保存操作数和操作符:
最后,栈中剩下的数即为表达式的值。
def evaluate_expression(expression: str) -> Union[int, str]:
"""
计算数值表达式的值
:param expression: 字符串数值表达式
:return: 求值结果或错误信息
"""
operators = {
'+': 1,
'-': 1,
'*': 2,
'/': 2,
'%': 2,
'^': 3,
'sqrt': 4,
'sin': 4,
'cos': 4,
'tan': 4
}
operator_stack = []
operand_stack = []
i = 0
while i < len(expression):
if expression[i].isdigit():
j = i
while j < len(expression) and expression[j].isdigit():
j += 1
num = int(expression[i:j])
operand_stack.append(num)
i = j
elif expression[i] in operators:
while operator_stack and operator_stack[-1] != '(' and operators[expression[i]] <= operators[operator_stack[-1]]:
operator = operator_stack.pop()
if operator in ['+', '-', '*', '/', '%', '^']:
b = operand_stack.pop()
a = operand_stack.pop()
if operator == '+':
operand_stack.append(a + b)
elif operator == '-':
operand_stack.append(a - b)
elif operator == '*':
operand_stack.append(a * b)
elif operator == '/':
operand_stack.append(a // b)
elif operator == '%':
operand_stack.append(a % b)
elif operator == '^':
operand_stack.append(a ** b)
elif operator == 'sqrt':
operand_stack.append(int(operand_stack.pop() ** 0.5))
elif operator == 'sin':
operand_stack.append(int(math.sin(math.radians(operand_stack.pop()))))
elif operator == 'cos':
operand_stack.append(int(math.cos(math.radians(operand_stack.pop()))))
elif operator == 'tan':
operand_stack.append(int(math.tan(math.radians(operand_stack.pop()))))
operator_stack.append(expression[i])
i += 1
elif expression[i] == '(':
operator_stack.append(expression[i])
i += 1
elif expression[i] == ')':
while operator_stack[-1] != '(':
operator = operator_stack.pop()
if operator in ['+', '-', '*', '/', '%', '^']:
b = operand_stack.pop()
a = operand_stack.pop()
if operator == '+':
operand_stack.append(a + b)
elif operator == '-':
operand_stack.append(a - b)
elif operator == '*':
operand_stack.append(a * b)
elif operator == '/':
operand_stack.append(a // b)
elif operator == '%':
operand_stack.append(a % b)
elif operator == '^':
operand_stack.append(a ** b)
elif operator == 'sqrt':
operand_stack.append(int(operand_stack.pop() ** 0.5))
elif operator == 'sin':
operand_stack.append(int(math.sin(math.radians(operand_stack.pop()))))
elif operator == 'cos':
operand_stack.append(int(math.cos(math.radians(operand_stack.pop()))))
elif operator == 'tan':
operand_stack.append(int(math.tan(math.radians(operand_stack.pop()))))
operator_stack.pop()
i += 1
while operator_stack:
operator = operator_stack.pop()
if operator in ['+', '-', '*', '/', '%', '^']:
b = operand_stack.pop()
a = operand_stack.pop()
if operator == '+':
operand_stack.append(a + b)
elif operator == '-':
operand_stack.append(a - b)
elif operator == '*':
operand_stack.append(a * b)
elif operator == '/':
operand_stack.append(a // b)
elif operator == '%':
operand_stack.append(a % b)
elif operator == '^':
operand_stack.append(a ** b)
elif operator == 'sqrt':
operand_stack.append(int(operand_stack.pop() ** 0.5))
elif operator == 'sin':
operand_stack.append(int(math.sin(math.radians(operand_stack.pop()))))
elif operator == 'cos':
operand_stack.append(int(math.cos(math.radians(operand_stack.pop()))))
elif operator == 'tan':
operand_stack.append(int(math.tan(math.radians(operand_stack.pop()))))
if len(operand_stack) == 1:
return operand_stack[0]
else:
return 'ERROR'
该算法的时间复杂度为 $O(n)$,其中 $n$ 为输入字符串的长度。算法使用了两个栈,空间复杂度为 $O(n)$。