如何使用逻辑运算符

时间:2018-01-18 06:45:25

标签: algorithm operators prefix

我有一个带有多个AND和OR运算符的前缀表达式,创建一个超过1的级别,我编写的算法对于单个深度工作正常但是将结果搞砸了超过1的深度。我正在使用python < / p>

前缀列表: - ['OR', 'AND', '=', ['.', 'grade'], 12, '>=', ['.', 'gpa'], ['.', '$', 'GPA'], 'AND', '=', ['.', 'a'], ['.', 'b'], '>', ['.', 'c'], ['.', 'd']]

def prefix_evaluation(prefix_list):
    opstack = []
    operand_stk = []
    pending_opd = False
    for token in prefix_list:
        if token in operators:
            opstack.append(token)
            pending_opd = False
        else:
            operand = token
            if pending_opd:
                while len(operand_stk) > 0:
                    opd_1 = operand_stk.pop()
                    operator  = opstack.pop()
                    operand = [operator, opd_1, operand]
            operand_stk.append(operand)
            pending_opd = True
    return operand_stk.pop()

预期结果:

[ OR,
    [ AND,
         [ AND,
              [ '=', ['.', 'grade'], 12],
              [ '>=', ['.', 'gpa'], ['.', '$', 'GPA']]
         ]
         [ AND,
              ['=', ['.', 'a'], ['.', 'b']],
              ['>', ['.', 'c'], ['.', 'd']]
         ]
    ]
]

实际结果:

['OR',
     ['AND', 
           ['AND', 
                ['=', ['.', 'grade'], 12], 
                ['>=', ['.', 'gpa'], 
                ['.', '$', 'GPA']]], 
           ['=', ['.', 'a'], ['.', 'b']]],
     ['>', ['.', 'c'], ['.', 'd']]]

1 个答案:

答案 0 :(得分:0)

为了使列表更具可读性,我已将所有操作数替换为n,例如12['.', 'grade']['.', 'c']等等。此外,我已将所有算术运算符替换为=,例如'>=''>'

现在,您的列表看起来像OR AND = n n = n n AND = n n = n n

我使用了圆形,方形,花括号来强调这些术语如何组合在一起 - 或者应该将这些术语组合在一起

enter image description here

(= n n)实际上是一个由一个运算符和两个操作数组成的列表,例如['>=', 12, 12]

显示预期结果和实际结果之间差异的图形透视图如下: enter image description here

当程序解析子列表OR AND = n n = n n时,它将形成操作数[AND (= n n) (= n n)](以及仍在运算符堆栈中的额外OR)。如您所见,此操作数对于预期结果和实际结果都是通用的。

当程序解析子列表OR AND = n n = n n AND = n n时(注意额外的AND = n n),它将具有已形成的[AND (= n n) (= n n)]操作数以及新的运算符{{ 1}}和操作数AND。它将分组为(=n n)。这就是程序的作用,它的编写方式。现在有办法告诉你的程序:嘿,需要形成第二个{AND [AND (= n n) (= n n)] (= n n) },然后才将这两个[AND (= n n) (= n n)]连接起来。

举一个类比,这就像期望一个逐字符读取的解析器意识到1 + 2 * 3不是(1 + 2)* 3,而是1+(2 * 3),除非你指定某种方式乘法优先于加法。

这里的缺陷是你在算术和逻辑运算符的同一篮子。难怪他们在构建表达式时具有相同的优先级(优先级)。

更好的方法是区分算术表达式,如 OR(= n n)之类的逻辑表达式,通过将它们放在两个不同的堆栈中,以及用于基本操作数的第三个堆栈,如[AND E1 E2]。还将像n这样的算术运算符放在与=之类的逻辑运算符不同的堆栈中。只有现在你可以强制规定'AND'运算符应该只链接两个算术表达式或两个逻辑表达式,而不是一个逻辑表达式算术,以避免当前输出并得到预期的一个。

但我觉得堆栈方法很麻烦,最好像有人建议的那样使用递归。