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

时间:2011-06-08 09:00:20

标签: algorithm data-structures tree suffix-tree

我读过:

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

但是在每个点上,我们必须选择要采用的分支,因此就像在n-ary树中一样,在每个节点处,我们必须与该节点中的所有最大n个指针进行比较,以决定采用哪个分支。这不会给这个算法的复杂性带来因素,不知何故在图片中

然后如何说它可以在O(m)中找到子串?

我在这里缺少什么?

2 个答案:

答案 0 :(得分:5)

  

然后如何说它可以在O(m)中找到子串?

遗漏。你是正确的,在后缀树中搜索的运行时间比仅仅O(m)更复杂。

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

例如,假设您使用C ++进行实现,而您的角色(char)可以包含256个不同的值。然后,节点的实现可能如下所示:

struct node {
    char current_character;
    node* children[256];
};

现在,current_character指的是指向当前节点的分支的字符,children是一个子节点数组。在搜索过程中,假设您当前位于节点u,输入文本中的下一个字符为c。然后,您将选择下一个节点,如下所示:

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)。

答案 1 :(得分:0)

如果指向子节点的指针在字母索引的数组中,则每个模式字母只需要不变的时间

node = tree root
FOR i in 1..m
   node = child[pat[i]]

因此复杂度为O(m)。