Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 如何将一棵树与一大组模式相匹配?_Algorithm_Optimization_Data Structures_Tree_Pattern Matching - Fatal编程技术网

Algorithm 如何将一棵树与一大组模式相匹配?

Algorithm 如何将一棵树与一大组模式相匹配?,algorithm,optimization,data-structures,tree,pattern-matching,Algorithm,Optimization,Data Structures,Tree,Pattern Matching,我有一组潜在的无限符号:a、B、C、还有一个独特的特殊占位符符号?(其含义将在下面解释) 考虑非空有限树,这样每个节点都有一个附加的符号和0个或多个非空子树。给定节点的子树顺序是重要的(因此,例如,如果有一个节点有两个子树,我们可以区分哪个是左的,哪个是右的)。任何给定的符号都可以在附加到不同节点的树中出现0次以上。占位符符号?只能附加到叶节点(即没有子树的节点)。根据树的通常定义,树是非循环的 有限性要求意味着树中的节点总数为正有限整数。因此,附加符号的总数、树深度和每个子树中的节点总数都是有

我有一组潜在的无限符号:
a、B、C、
还有一个独特的特殊占位符符号
(其含义将在下面解释)

考虑非空有限树,这样每个节点都有一个附加的符号和0个或多个非空子树。给定节点的子树顺序是重要的(因此,例如,如果有一个节点有两个子树,我们可以区分哪个是左的,哪个是右的)。任何给定的符号都可以在附加到不同节点的树中出现0次以上。占位符符号
只能附加到叶节点(即没有子树的节点)。根据树的通常定义,树是非循环的

有限性要求意味着树中的节点总数为正有限整数。因此,附加符号的总数、树深度和每个子树中的节点总数都是有限的

树以函数表示法给出:节点由附加到它的符号表示,如果有任何子树,则它后面的括号包含以逗号分隔的子树列表,这些子树以相同的方式递归表示。比如说树

                    A
                   / \
                  ?   B
                     / \
                    A   C
                   /|\
                  A C Q
                       \
                        ?
表示为
A(?,B(A(A,C,Q(?),C))

我有一个预先计算的不变树集S,将用作匹配的模式。该集合通常有约105棵树,每个its元素通常有约10-30个节点。我可以用大量的时间事先创建最适合我下面所述问题的S表示

我需要编写一个函数来接受树T(通常有约102个节点),并尽快检查T是否包含S的任何元素作为子树,前提是任何带有占位符符号
的节点都匹配任何非空子树(当它出现在TS元素中时)

请建议存储集合的数据结构和检查匹配的算法。任何编程语言或伪代码都可以。

描述了的一种变体,其中不使用有限状态机(标准Aho–Corasik算法用于字符串匹配)该算法使用下推自动机进行子树匹配。与Aho Corasick字符串匹配算法一样,它们的变体只需通过输入树一次,即可与整个S字典进行匹配


这篇论文相当复杂——看看他是否有可用的源代码是值得的。

你需要的是一个有限状态机,它可以跟踪你可能拥有的一组潜在匹配

本质上,这种机器是模式相互匹配的结果,并确定它们共享的单个匹配部分。这类似于lexer如何将一组正则表达式作为标记,并将它们组合成一个大的FSA,该FSA可以通过一次处理一个字符来匹配任何正则表达式输入法


您可以在下找到执行此操作的方法的参考。

尝试研究“常规树语法”和树自动机。@tmyklebu
A(?)
被视为模式意味着附加符号
A
的节点正好有一个子树。因此,它不匹配
A(B,C)
A
,但它将匹配
A(B)
A(B(C,D))
@jwpat7我在有两个子树的节点的情况下提到了左子树和右子树。如果一个节点只有一个子树,则不管子树在可视化图上的位置如何。没有空的子树-因此,没有
A(,B)
。符号
Q(?)
表示节点
Q
,其中单个子树由带有占位符符号的单个节点组成
。如果将其视为一种模式,则它会将任何树与根节点
Q
匹配,并精确匹配任何形式的一个非空子树,例如
Q(a)
Q(a(B,C(D)))
..@jwpat7…但是
Q(?)
不匹配
Q
(0子树)、
Q(A,B)
(2子树)或
A(Q)
(根上的符号错误)。但是它匹配
,因为占位符
代表任何树,包括那些可以由
Q(?)匹配的无占位符树因此,考虑到一个匹配的可能性,我们认为匹配是成功的。也可以看出,因为<代码> <代码>是一个更一般(更包容)的模式,而不是<代码>(?)>代码>,该匹配在另一个方向上有效地执行(即<代码> <代码> >匹配任何树,包括<代码> q(?)<代码>。。对不起,我没有解释我问题中的最后一点。@jwpat7…我想,更清楚的解释应该是当两个“模式”树(S的一个元素)都是一个“数据”树不包含占位符
,匹配被认为是成功的存在一个无占位符的树可以被“模式”树和“数据”树成功匹配(换句话说,当模式重叠时)。+1.在检查本文时,它似乎比我的建议更符合OP的要求。