新手求助:如何为自定义计算器添加多嵌套括号支持?
给新手的计算器括号支持实现方案
核心思路
用递归处理括号是最容易理解的方式:括号是嵌套结构,遇到左括号(时,就递归计算括号内的完整表达式,直到找到对应的右括号),把括号内的计算结果替换掉整个括号部分,再继续处理剩下的表达式。
修改后的完整代码
def parse_expression(expr, calculate_func): elements = list(expr.replace(" ", "")) exercise = [] operators = ('+', '-', '*', '/', '$', '&', '@') # @ = Average, & = Min, $ = Max i = 0 while i < len(elements): if elements[i] == '(': # 寻找匹配的右括号,处理多层嵌套 bracket_count = 1 j = i + 1 while j < len(elements) and bracket_count > 0: if elements[j] == '(': bracket_count += 1 elif elements[j] == ')': bracket_count -= 1 j += 1 # 提取括号内的子表达式并递归计算 sub_expr = ''.join(elements[i+1:j-1]) sub_result = calculate_func(sub_expr) if sub_result is None: return None exercise.append(sub_result) i = j # 跳过整个括号区域 elif elements[i] == ')': print("ERROR: Mismatched parentheses.") return None elif elements[i].isdigit() or (elements[i] == '-' and (i == 0 or elements[i - 1] in operators)): num = elements[i] while i + 1 < len(elements) and (elements[i + 1].isdigit() or elements[i + 1] == '.'): i += 1 num += elements[i] exercise.append(float(num)) elif elements[i] in operators: exercise.append(elements[i]) else: print(f"ERROR: Invalid character '{elements[i]}'.") return None i += 1 return exercise def calculate_result(expr): # 先解析表达式(处理括号) exercise = parse_expression(expr, calculate_result) if exercise is None: return None # 检查是否有有效数字 if len([s for s in exercise if isinstance(s, float)]) == 0: print("Invalid input.") return None # 处理$ & @ 运算符(优先级最高) k = 0 while k < len(exercise): if exercise[k] in ('$', '&', '@'): if k - 1 < 0 or k + 1 >= len(exercise) or not (isinstance(exercise[k-1], float) and isinstance(exercise[k+1], float)): print("ERROR: Invalid use of operator.") return None operator = exercise[k] left_num = exercise[k - 1] right_num = exercise[k + 1] if operator == '$': result = max(left_num, right_num) elif operator == '&': result = min(left_num, right_num) elif operator == '@': result = (left_num + right_num) / 2 exercise[k] = result exercise.pop(k + 1) exercise.pop(k - 1) else: k += 1 # 处理* / 运算符(优先级次之) k = 0 while k < len(exercise): if exercise[k] in ('*', '/'): if k - 1 < 0 or k + 1 >= len(exercise) or not (isinstance(exercise[k-1], float) and isinstance(exercise[k+1], float)): print("ERROR: Invalid use of operator.") return None operator = exercise[k] left_num = exercise[k - 1] right_num = exercise[k + 1] if operator == '*': result = left_num * right_num elif operator == '/': try: if right_num == 0: raise ZeroDivisionError result = left_num / right_num except ZeroDivisionError: print("ERROR: Can't divide by zero.") return None exercise[k] = result exercise.pop(k + 1) exercise.pop(k - 1) k -= 1 # 回退一步,避免跳过前面的运算符 k += 1 # 处理+ - 运算符(优先级最低) k = 0 while k < len(exercise): if exercise[k] in ('+', '-'): if k - 1 < 0 or k + 1 >= len(exercise) or not (isinstance(exercise[k-1], float) and isinstance(exercise[k+1], float)): print("ERROR: Invalid use of operator.") return None operator = exercise[k] left_num = exercise[k - 1] right_num = exercise[k + 1] if operator == '+': result = left_num + right_num elif operator == '-': result = left_num - right_num exercise[k] = result exercise.pop(k + 1) exercise.pop(k - 1) else: k += 1 if len(exercise) != 1: print("ERROR: Invalid expression.") return None return round(exercise[0], 2) while True: expr = input("calc> ") if expr.lower() == 'exit': print("Bye") break result = calculate_result(expr) if result is not None: print(f"{expr} = {result}")
关键改动说明
递归处理括号
- 遇到左括号时,用
bracket_count统计括号数量,确保找到匹配的右括号(支持多层嵌套)。 - 提取括号内的子表达式,递归调用
calculate_result计算结果,把结果作为数字加入解析列表,跳过整个括号区域。 - 增加括号不匹配的错误提示,比如单独出现
)时直接报错。
- 遇到左括号时,用
调整函数调用逻辑
- 让
calculate_result先调用parse_expression处理括号,形成完整的递归计算流程。 parse_expression接收calculate_func参数,用于递归调用计算子表达式。
- 让
增强错误处理
- 检查运算符左右是否有有效数字,避免非法表达式(比如
3+$5)。 - 最终结果列表长度必须为1,否则判定为无效表达式。
- 简化
exit输入的判断逻辑。
- 检查运算符左右是否有有效数字,避免非法表达式(比如
递归逻辑示例
比如输入((15&9)@(4*3))-2:
- 先计算最内层的
15&9=9和4*3=12; - 再计算
9@12=10.5; - 最后计算
10.5-2=8.5。
内容的提问来源于stack exchange,提问作者fastQ
相关产品推荐
相关产品推荐

