如何用Python实现表达式分步计算并处理此类分步输出结果?
Python实现表达式分步求值
实现思路
- 预处理表达式:区分显示用表达式(保留原符号如
^、–)和计算用表达式(转换为Python兼容的**、-)。 - 按运算优先级逐步匹配并计算子表达式:优先级从高到低为「括号内幂运算 > 括号内乘除 > 括号内加减 > 全局幂运算 > 全局乘除 > 全局加减」。
- 每计算一个子表达式,就替换显示用表达式中的对应部分,输出当前步骤,直到表达式简化为单一数值。
完整代码实现
import re def step_by_step_eval(original_expr): # 初始化显示用表达式和计算用表达式 display_expr = original_expr # 转换为Python可计算的表达式:^→**,全角减号→半角减号 compute_expr = original_expr.replace('^', '**').replace('–', '-') # 定义匹配规则:(计算用正则, 计算替换式, 显示用正则),按优先级从高到低排列 pattern_rules = [ # 括号内的幂运算 (r'\(([^\(\)]*?)(\d+)\^(\d+)([^\(\)]*?)\)', r'\(\1\2**\3\4\)', r'\(([^\(\)]*?)(\d+)\^(\d+)([^\(\)]*?)\)'), # 括号内的乘除运算 (r'\(([^\(\)]*?)(\d+)\s*([*/])\s*(\d+)([^\(\)]*?)\)', r'\(\1\2\3\4\5\)', r'\(([^\(\)]*?)(\d+)\s*([*/])\s*(\d+)([^\(\)]*?)\)'), # 括号内的加减运算 (r'\(([^\(\)]*?)(\d+)\s*([+-])\s*(\d+)([^\(\)]*?)\)', r'\(\1\2\3\4\5\)', r'\(([^\(\)]*?)(\d+)\s*([+-])\s*(\d+)([^\(\)]*?)\)'), # 全局幂运算 (r'(\d+)\^(\d+)', r'\1**\2', r'(\d+)\^(\d+)'), # 全局乘除运算 (r'(\d+)\s*([*/])\s*(\d+)', r'\1\2\3', r'(\d+)\s*([*/])\s*(\d+)'), # 全局加减运算 (r'(\d+)\s*([+-])\s*(\d+)', r'\1\2\3', r'(\d+)\s*([+-])\s*(\d+)'), ] print(f'原始表达式: {original_expr}') while True: # 检查是否已简化为单一数值 stripped_expr = display_expr.replace(' ', '') if re.fullmatch(r'-?\d+(\.\d+)?', stripped_expr): print(f'{" " * 21}= {display_expr}') break found_match = False for comp_pattern, comp_replace, disp_pattern in pattern_rules: # 在显示表达式中查找当前优先级的子式 match = re.search(disp_pattern, display_expr) if match: # 提取子表达式并转换为可计算格式 sub_comp_expr = re.sub(comp_pattern, comp_replace, match.group(0)) # 计算子表达式结果 result = eval(sub_comp_expr) # 整数结果转成int类型,避免显示为7.0 result = int(result) if result.is_integer() else result result_str = str(result) # 替换显示表达式中的子式 old_sub = match.group(0) display_expr = display_expr.replace(old_sub, result_str, 1) # 更新计算表达式 compute_expr = compute_expr.replace(old_sub.replace('^', '**').replace('–', '-'), result_str, 1) # 输出当前步骤(对齐格式) print(f'{" " * 21}= {display_expr}') found_match = True break if not found_match: break # 测试示例 input_expression = "(2 + 3 * 4) / 2 – (3^2 - 3)" step_by_step_eval(input_expression)
代码说明
- 双表达式维护:
display_expr:始终保留用户输入的原始符号(如^、–),用于输出分步过程。compute_expr:转换为Python支持的运算符号,用于调用eval()计算子式结果。
- 正则匹配优先级:
按运算优先级顺序定义正则规则,确保每一步优先计算当前最高优先级的子表达式,符合数学运算逻辑。 - 结果格式化:
将浮点整数(如7.0)转换为整数类型,保证输出格式与预期一致;通过固定空格数实现步骤行的对齐。
运行结果
原始表达式: (2 + 3 * 4) / 2 – (3^2 - 3) = (2 + 12) / 2 – (3^2 - 3) = 14 / 2 – (3^2 - 3) = 7 – (3^2 - 3) = 7 – (9 - 3) = 7 – 6 = 1
内容的提问来源于stack exchange,提问作者Bảo Huy
相关产品推荐
相关产品推荐

