Algorithm 使用后缀树在字符串中搜索子字符串。。?

Algorithm 使用后缀树在字符串中搜索子字符串。。?,algorithm,data-structures,tree,suffix-tree,Algorithm,Data Structures,Tree,Suffix Tree,我读到: 在txt[1..n]中搜索子字符串pat[1..m]可以在O(m)时间内解决(在O(n)时间内建立txt的后缀树之后)。 但在每一点上,我们必须选择要采用的分支,就像在n元树中一样,在每个节点上,我们必须与该节点中的所有max n指针进行比较,以决定采用哪个分支。这会不会给这个算法的复杂度带来n个因素,不知怎么的 那么上面怎么说子串可以在O(m)中找到呢 这里缺少什么?如果指向child的指针位于按字母索引的数组中,则每个模式字母只需要固定的时间 node = tree root FO

我读到:

在txt[1..n]中搜索子字符串pat[1..m]可以在O(m)时间内解决(在O(n)时间内建立txt的后缀树之后)。

但在每一点上,我们必须选择要采用的分支,就像在n元树中一样,在每个节点上,我们必须与该节点中的所有max n指针进行比较,以决定采用哪个分支。这会不会给这个算法的复杂度带来n个因素,不知怎么的

那么上面怎么说子串可以在O(m)中找到呢


这里缺少什么?

如果指向child的指针位于按字母索引的数组中,则每个模式字母只需要固定的时间

node = tree root
FOR i in 1..m
   node = child[pat[i]]
所以复杂性是O(m)

那么上面怎么说子串可以在O(m)中找到呢

由于疏忽。在后缀树中搜索的运行时比仅仅O(m)更复杂,这是正确的

然而,如果我们权衡空间需求,它确实可以加速到O(m):我们需要将每个节点的搜索降低到O(1),我们可以通过使用适当的数据结构(例如数组)来实现这一点,该结构在恒定时间内为每个字母提供适当的子树

例如,假设你正在使用C++来实现,你的字符(<代码> char < /代码>)可以包含256个不同的值。然后节点的实现可以如下所示:

struct node {
    char current_character;
    node* children[256];
};
node* next = u->children[c];
if (next == 0) {
    // Child node does not exist => nothing found.
}
else {
    u = next;
    // Continue search with next …
}
现在,
current\u character
是指向当前节点的分支的字符,
children
是子节点的数组。在搜索过程中,假设您当前位于节点
u
,输入文本中的下一个字符是
c
。然后,您将选择下一个节点,如下所示:

struct node {
    char current_character;
    node* children[256];
};
node* next = u->children[c];
if (next == 0) {
    // Child node does not exist => nothing found.
}
else {
    u = next;
    // Continue search with next …
}

当然,这只适用于非常小的字母表(例如基因组序列的DNA)。在大多数常见情况下,后缀树的最坏运行时间确实高于O(m)。

好的,我不知道后缀树在实践中是如何实现的。但是如何使数组在字符上保持不灵活呢?这是什么样的空间复杂性?有26个小写字母。因此,对于每个节点,我们要保留一个大小为26*的指针数组。这听起来太浪费空间了。在另一种方法中,您可以在每个节点中有一个指针列表,因此一个节点中的时间是O(a)(a是字母表大小),而查找子字符串的时间是O(m*a)。假设A为常数,我们再次得到O(m)。是否有明确的功能实现,以及在线描述。我很惊讶谷歌搜索并没有取得成果。除了理论之外,如何在javascript中实现后缀树,并搜索匹配的子字符串,以便返回最接近的结果?目的是一个自动完成字段。好了,有没有指向后缀树的实际实现的指针?请看我对上面其他答案的评论。后缀树在实践中是如何表示的?我们能用图中的邻接表来表示它吗?