Python 树匹配算法?
我正在开发一个库,所需功能的一部分是能够在节点中搜索与模式匹配的子节点 “模式”是一种规范(或标准),它列出了结构以及要匹配的子树中节点的属性 例如,假设一棵树代表一种特定鸟类的数据。进一步假设该树的节点具有以下属性:Python 树匹配算法?,python,algorithm,tree,Python,Algorithm,Tree,我正在开发一个库,所需功能的一部分是能够在节点中搜索与模式匹配的子节点 “模式”是一种规范(或标准),它列出了结构以及要匹配的子树中节点的属性 例如,假设一棵树代表一种特定鸟类的数据。进一步假设该树的节点具有以下属性: 位置 性 翼展 重量 窝大小 给定一个父节点,我想用简单的英语进行搜索,因此: “把所有的雄性鸟都给我拿来 这种鸟的后代,生活在 XXX城市,体重>100克。发现的任何此类鸟还应至少有两个兄弟和一个姐妹,并且自身必须至少有一个孩子。” 我只是想澄清一下,我不希望能够像上面那
- 位置
- 性
- 翼展
- 重量
- 窝大小
虽然我要求提供一个通用算法,但我正在用Python实现它。任何进一步说明这种算法的代码片段(如果确实可以编写的话)都会非常有用。用通配符来描述树匹配有什么错?括号将节点分组。元素从左到右匹配根,后跟子元素。子树匹配使用嵌套的六进制表达式来描述子树 以下内容将匹配具有任意根节点的树,第一个子节点是叶a,第三个子节点是以X为根的子树,第一个子节点1和第三个子节点a:
(?root A ? (X 1 A))
这个想法不是我独有的;口齿不清的人从60年代初就开始写这种模式
下面是一个LISP模式匹配器(作为您想要的示例),它可以追溯到20年前:
然而,自己编写代码是相当容易的。这通常被指定为学习LISP的人的家庭作业练习。这取决于您的树。如果你的树是根的,并且是有序的,你应该能够在次线性时间内检查精确的匹配,如果不是,你应该能够在线性时间内检查匹配。对于近似匹配,还存在几种更快的算法 为这样的主题寻找材料和算法,是你的朋友。搜索匹配的子树或类似的子树应该会让你达到目的 编辑:根据您更新的条目判断,我建议您看看XPath和类似查询语言是如何实现的。XML是一个有根树,XPath可以使用复杂的匹配运算符(如示例中的运算符)在该树中搜索子树
我还建议您不要自己实现这个功能,而是使用现有的库(如或其他搜索引擎,根据您给出的示例,这似乎是合适的)。使用递归列表可能要好得多,实际上,您只需使用中间列表即可➔ 一串➔ 正则表达式➔ 列出可能不值得花费的开销。一个更具体的例子可以帮助你得到一个更好的答案。你有两个问题:A)如何将树模式匹配表示为一个正式的可解释实体,b)将自由文本英语查询转换为这样的模式。a) 是众所周知的;请参阅我的答案中的一个选项。b) 仍然是一个研究课题;我怀疑你是否想自己尝试。@Ira:我只是用“简明英语查询”来说明我想在树上执行的匹配类型。我希望在实践中使用符号来匹配(而不是纯文本)——我想我会编辑我的帖子来澄清这一点,谢谢!。知道这是可以做到的,而且事实上已经做到了20年,这让人感到放心。。。现在尝试在Python中实现:)+1当我阅读您的需求(@morpheus)时,我认为这似乎是一个非常适合sql的问题,而lisp方法是最接近“在软件中”(不使用db)的方法。@DaveO现在我很好奇,这在sql中怎么会是一个非常适合的问题?我的想法正好相反,当你的问题是关于树和模式时,在集合和字段上操作既不容易,也不高效。@DaveO:我是j-a的。SQL是存储和匹配树结构的糟糕引擎。SQL在有多组记录要处理时工作得最好;树的导航通常一次只完成一个节点。有人可能会将树匹配转换为单个节点的匹配以及它们之间的父子关系,但我怀疑由匹配节点类型选择的记录数量会非常多,而由父子关系选择的记录数量会非常多,因此正如DaveO所说,“效率也不高”。是的,我不相信重新发明轮子。事实上,我一直在考虑XPath是如何工作的。。。就函数而言,传递给函数fetch_matching_subtrees()的节点是根节点。但是我没有想到Lucene引擎。值得深思的是。。。