我有一个带有多个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']]]
答案 0 :(得分:0)
为了使列表更具可读性,我已将所有操作数替换为n
,例如12
,['.', 'grade']
,['.', 'c']
等等。此外,我已将所有算术运算符替换为=
,例如'>='
,'>'
。
现在,您的列表看起来像OR AND = n n = n n AND = n n = n n
我使用了圆形,方形,花括号来强调这些术语如何组合在一起 - 或者应该将这些术语组合在一起
(= n n)
实际上是一个由一个运算符和两个操作数组成的列表,例如['>=', 12, 12]
当程序解析子列表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'运算符应该只链接两个算术表达式或两个逻辑表达式,而不是一个逻辑表达式算术,以避免当前输出并得到预期的一个。
但我觉得堆栈方法很麻烦,最好像有人建议的那样使用递归。