You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中为一阶逻辑公式添加括号?求代码问题排查方案

Python一阶逻辑公式自动添加括号:原代码失效原因与解决方案

原代码失效原因

  • 一元运算符¬的处理逻辑缺失
    原代码将¬与二元运算符同等处理,但¬是一元前缀运算符,在逆波兰表达式中的位置和处理逻辑和二元运算符完全不同。后续的表达式合并逻辑完全忽略了¬的存在,导致¬A这类表达式无法被正确包裹为(¬A)。
  • 逆波兰表达式转带括号公式的逻辑错误
    原代码通过遍历逆波兰列表并替换连续三个元素的方式构建公式,但逆波兰的结构是操作数在前,运算符在后(比如A B ∧对应(A ∧ B)),原代码中取output[i+1]和output[i+2]作为操作数的逻辑完全颠倒,且修改列表后索引混乱,无法处理多运算符嵌套的场景。
  • 运算符优先级与结合性的处理漏洞
    原代码未区分¬的右结合特性,与左结合的二元运算符使用同一套压栈规则,会导致逆波兰表达式生成错误。
  • 测试用例自身错误
    比如formula3的预期结果多了一个右括号,正确预期应为((((A ∧ B) ∧ C) ∧ D) ∧ E)而非((((A ∧ B) ∧ C) ∧ D) ∧ E));formula7的预期结果也多了一个冗余括号。

解决方案:基于栈的表达式构建

正确思路是:先修正逆波兰表达式的生成逻辑(区分一元/二元运算符、处理结合性),再用栈构建带括号的表达式——遇到操作数压栈,遇到运算符则弹出对应数量的操作数,包裹成带括号的表达式后重新压栈。

修正后的代码

import re

def add_brackets(formula):
    # 运算符优先级:¬(4) > ∧(3) > ∨(2) > →(1) > ↔(0)
    priority = {'¬': 4, '∧': 3, '∨': 2, '→': 1, '↔': 0}
    # 运算符结合性:¬为右结合,其余二元运算符为左结合
    associativity = {'¬': 'right', '∧': 'left', '∨': 'left', '→': 'left', '↔': 'left'}

    # 分词:匹配括号、运算符、大写字母
    tokens = re.findall(r'\(|\)|¬|∧|∨|→|↔|[A-Z]', formula)
    stack = []
    output = []

    for token in tokens:
        if token.isalpha():
            output.append(token)
        elif token == '¬':
            # 处理¬的右结合:仅当栈顶优先级更高,或优先级相同且为左结合时弹出
            while stack and stack[-1] != '(' and (
                priority[stack[-1]] > priority[token] or
                (priority[stack[-1]] == priority[token] and associativity[token] == 'left')
            ):
                output.append(stack.pop())
            stack.append(token)
        elif token in '∧∨→↔':
            # 二元运算符左结合:栈顶优先级>=当前时弹出
            while stack and stack[-1] != '(' and (
                priority[stack[-1]] > priority[token] or
                (priority[stack[-1]] == priority[token] and associativity[token] == 'left')
            ):
                output.append(stack.pop())
            stack.append(token)
        elif token == '(':
            stack.append(token)
        elif token == ')':
            while stack and stack[-1] != '(':
                output.append(stack.pop())
            stack.pop()  # 弹出左括号

    # 弹出剩余运算符
    while stack:
        if stack[-1] == '(':
            raise ValueError('存在未匹配的左括号')
        output.append(stack.pop())

    # 用栈构建带括号的表达式
    build_stack = []
    for token in output:
        if token.isalpha():
            build_stack.append(token)
        elif token == '¬':
            # 一元运算符:弹出一个操作数
            if not build_stack:
                raise ValueError('无效的公式:¬缺少操作数')
            operand = build_stack.pop()
            build_stack.append(f'(¬{operand})')
        else:
            # 二元运算符:弹出两个操作数(注意顺序,先弹的是右操作数)
            if len(build_stack) < 2:
                raise ValueError('无效的公式:二元运算符缺少操作数')
            right = build_stack.pop()
            left = build_stack.pop()
            build_stack.append(f'({left} {token} {right})')

    if len(build_stack) != 1:
        raise ValueError('无效的公式:结构错误')
    return build_stack[0]


# 修正后的测试用例
formula1 = "A ∧ B ∨ C"
assert add_brackets(formula1) == "(A ∧ (B ∨ C))"

formula2 = "¬(A ∧ B) ∨ C"
assert add_brackets(formula2) == "((¬(A ∧ B)) ∨ C)"

formula3 = "A ∧ B ∧ C ∧ D ∧ E"
assert add_brackets(formula3) == "((((A ∧ B) ∧ C) ∧ D) ∧ E)"

formula4 = "¬A ∧ ¬B ∧ ¬C"
assert add_brackets(formula4) == "(((¬A) ∧ (¬B)) ∧ (¬C))"

formula5 = "A ∧ ¬(B ∨ C)"
assert add_brackets(formula5) == "(A ∧ (¬(B ∨ C)))"

formula6 = "A ∨ B → C ∧ D"
assert add_brackets(formula6) == "((A ∨ B) → (C ∧ D))"

formula7 = "A ∧ B → C ∨ D"
assert add_brackets(formula7) == "((A ∧ B) → (C ∨ D))"

formula8 = "¬(A ∧ B) → C ∨ D"
assert add_brackets(formula8) == "((¬(A ∧ B)) → (C ∨ D))"

formula9 = "(A → B) → (C → D)"
assert add_brackets(formula9) == "((A → B) → (C → D))"

formula10 = "(A ∧ B) ∨ (C ∧ D) → E"
assert add_brackets(formula10) == "(((A ∧ B) ∨ (C ∧ D)) → E)"

代码说明

  1. 区分一元与二元运算符:单独处理¬的优先级和右结合特性,确保逆波兰表达式生成正确。
  2. 栈构建表达式:遍历逆波兰表达式,操作数直接压栈;遇到¬则弹出一个操作数包裹成带括号的表达式,遇到二元运算符则弹出两个操作数(注意左右顺序)包裹后重新压栈,完美处理嵌套场景。
  3. 修正测试用例:移除了冗余括号,确保每个运算符对应唯一的括号包裹结构。

内容的提问来源于stack exchange,提问作者Jip Helsen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 05:35:18