[英]how to evaluate prefix expression for with logical operator
我有一个带有多个AND和OR运算符的前缀表达式,创建的级别大于1,我编写的算法可以很好地处理单个深度,但将结果的深度大于1时搞砸了。我使用的是python
前缀列表:- ['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']]]
为了使列表更易读,我将所有操作数都替换为n
,例如12
, ['.', 'grade']
, ['.', 'c']
等。 另外,我用=
替换了所有算术运算符,例如'>='
, '>'
。
现在您的列表看起来像OR AND = nn = nn AND = nn = nn
我使用了圆,方,大括号来强调术语如何组合在一起-或应该组合在一起
(= nn)
实际上是一个由一个运算符和两个操作数组成的列表,例如['>=', 12, 12]
到程序解析子列表OR AND = nn = nn
的那一刻,它将形成操作数[AND (= nn) (= nn)]
(以及仍在运算符堆栈中的额外OR
)。 如您所见,此操作数对于预期结果和实际结果都是通用的。
程序解析完子列表OR AND = nn = nn AND = nn
(请注意额外的AND = nn
)时,它将具有已经形成的[AND (= nn) (= nn)]
操作数,以及新的运算符AND
和操作数(=nn)
。 它将分组为{AND [AND (= nn) (= nn)] (= nn) }
。 这就是程序的工作方式,以及编写方式。 现在确实有一种方法可以告诉您的程序:嘿,还需要形成第二个[AND (= nn) (= nn)]
,然后再将两者与OR
串联。
打个比方,这就像期望解析器逐个字符地读取,以意识到1 + 2 * 3不是(1 + 2)* 3,而是1+(2 * 3),除非您以某种方式指定乘法具有优先于加法。
这里的陷阱是算术和逻辑运算符都放在同一个篮子里。 难怪在构建表达式时它们具有相同的优先级(优先级)。
更好的方法是通过将算术表达式(= nn)
和逻辑表达式( [AND E1 E2]
)放在两个不同的堆栈中,以及用于基本操作数的第3个堆栈(如n
区分它们。 还要将=
等算术运算符与AND
逻辑运算符放在不同的堆栈中。 而且只有现在,您可以施加规则, 即“ AND”运算符应仅链接两个算术或两个逻辑表达式,而不能将一个算术与一个逻辑表达式链接在一起 ,以避免出现当前输出并获得预期的输出。
但是我觉得堆栈方法很麻烦,最好像有人建议的那样使用递归。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.