在查看了原始问题之后,我认为您误解了它。
这个问题是关于一AND/OR
棵树,其中最深层次的节点是AND
节点。其他节点的逻辑操作员是由这个因素决定的——我们最初不知道它们是不是AND
节点OR
,我们只知道最深层次的节点是AND
节点——所以下一个更高层次的节点是OR
节点,下一个更高级别是AND
节点,依此类推……逻辑操作符在树的不同深度之间交换。如果您查看AND/OR
他们提供的示例树,这将变得很清楚。
我解决这个问题的方法是首先找出根节点的逻辑连接词。这可以通过对表达式进行一次扫描并跟踪括号的数量来完成。请注意,每个都()
对应于树中的一个新节点(树的下一级)。例如,考虑以下表达式:
((F(TF))(TF))
当你走过这个表达式时,首先我们遇到 3 个左括号,2 个右括号,1 个左括号,最后是 2 个右括号。如果您在此步行期间的任何给定时间获取打开的最大括号数,它将是这AND/OR
棵树的最大深度(3
在上面的示例中)。
那么这是什么意思?如果树的深度是奇数,则根节点是一个AND
节点,否则根是一个OR
节点(因为连接词是交替的)。
一旦你知道了根节点的连接词,你就可以使用一个简单的基于堆栈的机器来评估这个表达式。我们需要记住,每次打开或关闭括号时,都需要翻转连接词。以下是上述表达式的求值方式:
AND |- (•(F(TF))(TF))
请注意,项目符号表示我们在表达式中的位置(如堆栈顶部)。然后我们继续如下:
OR |- ((•F(TF))(TF)) // flipped the connective because we jumped a node
OR |- ((F•(TF))(TF)) // nothing to evaluate on the current node, push F
AND |- ((F(•TF))(TF))
AND |- ((F(T•F))(TF))
AND |- ((F(TF•))(TF))
AND |- ((F(F•))(TF)) // Two booleans on top, T AND F = F (reduce)
OR |- ((F(F)•)(TF)) // Jumped out of a node, flip the sign
OR |- ((FF•)(TF)) // Completely evaluated node on top, (F) = F (reduce)
OR |- ((F•)(TF)) // Two booleans on top, F OR F = F (reduce)
AND |- ((F)•(TF))
AND |- (F•(TF))
OR |- (F(•TF))
OR |- (F(T•F))
OR |- (F(TF•))
OR |- (F(T•))
AND |- (F(T)•)
AND |- (FT•)
AND |- (F•)
所以你得到的最终答案是F
。这与shift-reduce 解析有一定关系,但这种情况下的减少取决于我们正在操作的 AST 的当前深度。我希望你能够将这个想法转化为代码(你需要一个堆栈和一个全局变量来跟踪当前有效的逻辑操作)。
最后,感谢您介绍该网站。您可能还喜欢这个网站。