如何反转字符串的后缀树(findind它表示的字符串)

给定一个(修改/断开)后缀树,它在每个边中存储当前子字符串的开始和结尾,但不存储子字符串本身,即后缀树如下所示: 在这里输入图像描述

这棵树表示字母表上的字符串“香蕉”:{a,b,n}。

我正在寻找的算法是找到一个这样的树代表的字符串,对于上面的例子,我希望算法找到“香蕉”。 我想在复杂的O(| string |)where | string |中 是正在搜索的字符串的长度。 可以假设:

字母表的大小是恒定的,并且每个字符串都从索引1开始。


  • 让我们从一些多项式时间解决方案开始:

  • 我们将字符串中的所有字符划分为等价类。

  • 我们已经知道:这是一个特殊的$符号。

  • 归纳假设:假设我们已经将长度为k的后缀的所有字符恰当地分成了等价类。 我们也可以对长度为k + 1的后缀进行适当的处​​理。

  • 证明:让我们迭代所有长度为i <- 1...k的长度并检查长度为k的后缀的最长公共前缀的长度和长度为i的后缀是否不为零。 如果相应叶子的最低共同祖先不是树的根,则它是非零的。 如果我们找到了这样的后缀,我们知道它的第一个字母等于当前后缀的第一个字母。 所以我们可以将长度为k + 1的后缀的第一个字母添加到适当的等价类中。 否则,它属于它自己的等价类。

  • 当所有角色被划分为等价类时,我们只需要为每个类指定一个唯一的符号(如果我们需要保持一个正确的字典顺序,我们可以检查其中哪一个更早出现。为此,我们需要查看从根开始的边的顺序)。

  • 时间复杂度是O(n ^ 3) (有n足够的,我们遍历O(n)其他每个足够的他们,我们计算他们的lca在O(n) (我假设我们在这里使用朴素算法) )。 到现在为止还挺好。

  • 现在让我们用几个观察来得到一个线性解决方案:

  • 我们并不需要这个lca。 我们只需要检查它不是根。 因此,我们可以根据它们的祖先,将所有叶子划分为等价类,这些祖先是根的直接子。 它可以使用深度优先搜索以线性时间完成。 两个足够的最长公共前缀是非空的,如果它们在同一个类中。

  • 我们实际上并不需要检查所有短的足够。 我们只需要检查距离左边和右边最近的一个搜索顺序。 从给定的左边到右边找到最接近的较小数字是一个标准问题,它有一个线性解决方案和一个堆栈。

  • 就是这样:我们至多检查给定的一个,每个检查是O(1) 。 我们现在有一个线性解决方案。

  • 此解决方案使用这样一个字符串确实存在的假设。 如果这种假设不可行,我们可以使用这种算法构造一些​​字符串,然后使用Ukkonnen算法为其构建线性后缀树,并检查它是否与给定的完全相同。

    链接地址: http://www.djcxy.com/p/40117.html

    上一篇: How to reverse a suffix tree of a string (findind the string it represents)

    下一篇: Generating suffixes from a Suffix Tree