这是伪作业(这是额外的功劳)。我有一个BST,它是指向包含单词的行(存储在其他地方)的单词索引。我需要实现一种使用s表达式进行搜索的方法,这样我就可以组合和(&)和or(|)。
在命令提示符处,用户可以输入类似:
的内容 QUERY ((((fire)&(forest))|((ocean)&(boat)))&(water))
基本上应该返回包含火,森林和水这些词的所有行以及包含海洋,船只和水的所有行。
我真正需要帮助的是解析和插入节点到树中的逻辑,以正确表示表达式而不是实际代码。我唯一能解决的问题是为表达式中的每个单词返回一组行。然后,根据它是“或”还是“和”操作,我将对这些集合执行联合或交集类型操作以创建新集合并将其传递到树上。
我对如何解析包含表达式的行感到很遗憾。经过一番思考后,似乎其中一个子表达式“越远”,它应该在我的s表达式树中越高?我想如果我能在正确的方向上推进,只要解析并在树中插入表达式,我就应该没问题。
我为上面的查询提出的示例树看起来像是;
&
/ \
| water
/ \
& &
/ \ / \
fire forest ocean boat
这是有道理的,因为火将返回一组所有包含火的线,而森林将返回一组包含森林的线。然后在“&”级别我将采用这两个集并创建另一个集合,其中只包含两个集合中的行,从而为我提供了一个只包含火和森林的行的集合。
我的另一个绊脚石是在克服解析障碍后如何表示树中的所有内容。我有一个ExpTreeNode类,它将作为我的ExpTree(BST)的节点,然后我有2个子类,运算符和操作数,但我不确定这是否是一个好的方法。
答案 0 :(得分:4)
Dijkstra已经为你完成了: - )
尝试分流码算法:http://en.wikipedia.org/wiki/Shunting-yard_algorithm
您可以使用分流场算法创建RPN(反向抛光表示法),一旦创建,您可以通过它来创建二叉树。
通常,RPN用于进行评估,但您实际上可以创建树。
例如,您可以创建树节点并将它们推送到堆栈中,而不是进行评估。
所以如果你看到node1,node2,operator。您创建一个新节点
Operator
/ \
node1 node2
然后将其推回堆栈。
更详细的例子:
表达式为(apples AND oranges) OR kiwis
这个RPN是kiwis oranges apples AND OR
现在在保持堆叠的同时走这条路。
将一个节点从kiwis推入堆栈。橙子节点推入堆栈。和苹果一样。
所以堆栈是
Node:Apples
Node:Oranges
Node:Kiwis
现在你在RPN中看到了AND。
您从堆栈中弹出前两个并创建一个新AND节点作为父节点。
节点:AND,[Node:Apples,Node:Oranges]
基本上是树
AND
/ \
Apples Oranges
现在将此节点推入堆栈。
所以堆栈是
Node:AND, [Node:Apples, Node:Oranges]
Node:Kiwis
现在你在RPN中看到了OR并创建了一个节点,其中OR为父节点:节点:节点和节点新手作为孩子获取树
OR
/ \
AND Kiwis
/ \
Apples Oranges
您甚至可以修改分流码算法来创建树,但处理RPN似乎更容易。
或者,您可以尝试使用递归下降分析技术。你问的是很常见的,如果你在网上搜索,你甚至可以找到语法和代码。
顺便说一句,你只是意味着二叉树对吗? BST(二进制搜索树)有一个额外的约束......