我们可以使用带有后缀树的圆形字符串吗?

时间:2012-11-15 18:16:04

标签: algorithm suffix-tree

我们可以使用带有后缀树的圆形字符串吗? 所以最后一个字符后跟列表中的第一个字符。

如果是这样,这个后缀树的表示与普通的后缀树有什么不同?

3 个答案:

答案 0 :(得分:1)

这取决于“使用”的含义。

<强> 1) 首先,以最直接的方式解释你的问题,考虑一个长度为n的圆形字符串,即每n个字符重复一次的无限字符串。这样的对象没有通常意义上的后缀,因为它永远不会结束,所以你不能构造它的后缀树。

2)然而,我们的想法当然是我们有一个圆形字符串的有限表示,它使用从最后一个字符到第一个字符的链接。以类似的方式,我们可以通过使用指向圆形后缀树的链接来扩展给定的后缀树,该后缀树表示圆形字符串的所有(无限长)后缀。请注意,不能通过从每个叶子插入到节点根节点的链接来完成,因为从根目录开始,所有字符串后缀的传出边缘,但是从这种圆形弦的叶子中,只能有一个外出边缘。示例:代表“mississippi $”后缀“ssippi $”的叶子应该有一个带有无限标签的传出边缘“mississippi $ mississippi $ mississippi $ ....”而没有其他边缘。如果你要将它链接到树的根,那么会有更多不正确的延续。

所以有两件事是必要的:

  • 离开叶子的边缘(毕竟这是一个有趣的概念)。每片叶子都有一个外出边缘。
  • 带有无限标签的边缘。此标签可以表示为圆形字符串(对于叶子的所有传出边缘,该圆形字符串将相同)。

这将为您提供圆形字符串的所有(无限)后缀的有效表示。

3)我不确定这种表示是否对任何事情有用。如果构造后缀树的目的是启用子字符串搜索,那么将圆形字符串的有限表示(不包括链接)连接到自身并从中构造后缀树的常用技巧应该足够,除非您搜索的子字符串本身比n个字符长。

同样重要的是要注意后缀树的某些其他用途需要引入更多的“无限”概念。例如,对于某些应用,可能需要在该节点中存储树节点的字符深度(即,从根到特定节点的边缘标签的组合长度)。在上面提出的“循环后缀树”中,叶子的外出边缘将导致某种特殊的“叶子在极限”并且带有圆形串作为标签。任何与这种圆形字符串匹配的查询都需要一种特殊的方法来跟踪匹配深度,因为该边缘上没有内部节点来存储深度信息。

4)说完所有这些之后,实际上至少有一个已知的后缀树应用于圆形字符串,但不是(1),(2)或(3)意义上的上面,即通过使用后缀树表示整个无限对象。相反,使用圆形字符串的有限子串的后缀树来解决按字典顺序最小旋转的问题。 Wikipedia描述了该问题,尽管其中列出的解决方案不包括任何使用后缀树的解决方案。但是,Dan Gusfield在Algorithms on Strings, Trees and Sequences的第7.13节中描述了解决方案。

这个想法是你考虑长度为n的字符串S的词典编码最小旋转集合等同于圆形字符串的第一个长度-n子串的集合。这个问题等同于找到按字典顺序排列的最小截止点。 Gusfield通过构造字符串SS $的后缀树来解决它,通过在每个节点处采用字典上最小的边来遍历此树,从而最终到达与按字典相对应的最小截止点对应的节点。

因此,正如(4)所示,在圆形字符串的上下文中存在后缀树的某些实际“用途”,但我不确定这是否是您感兴趣的用途。

答案 1 :(得分:0)

是的,你可以存储圆形字符串,因为字符串的长度是有限的。

让我们考虑一下banban这个词。

以下是结构

root -> b -> a -> n -> b -> a -> n -> $

                    -> $

root -> a -> n -> b -> a -> n -> $

                -> $

root -> n -> b -> a -> n -> $

          -> $

美元符号表示后缀终止

编辑:

使用Java编程语言可以找到一个简洁的后缀树实现here

编辑:正如评论部分所述:

“如果我有密西西比字符串,我想搜索'pim'怎么办?”

pim不是密西西比的后缀,因此搜索将失败。

编辑:但是pim在圆形字符串中,我想将它添加到trie中

为了做到这一点,你必须将prim视为一个单独的单词并将其添加到trie中以形成一个全局扩充后缀trie。

将anb视为原始单词banban的圆形字符串。

因此全局扩充后缀trie将是:

root -> b -> a -> n -> b -> a -> n -> $ (original word)

          -> a -> n -> $ (original word)

          -> $ (from anb)

root -> a -> n -> b -> a -> n -> $ (original word)

               -> $ (original word)

               -> b -> $ (from anb)

root -> n -> b -> a -> n -> $ (original word)

                -> $ (from anb)

          -> $ (original word)

答案 2 :(得分:0)

我会考虑您想要的内容,并考虑以下解决方法:

如果你有一个圆形字符串的后缀数组,这通常是字符串中的偏移列表,这样在每个偏移处开始的序列都是按排序顺序。

现在假设你有一个圆形的字符串,它是用ABCD包裹的。考虑通过将其自身的一个字符附加到其上而形成的字符串 - ABCDABC,以及如果从中构建后缀数组会发生什么。圆形字符串中的所有序列(ABCD BCDA CDAB DABC)都出现在ABCDABC中,因此当您从中构建后缀数组时,您将获得相同的后缀数组,就像您从圆形字符串构建它一样,其中一些序列上添加了字符结束(ABCDABC而不是ABCD)和一些太短的额外序列(ABC)。您可以通过查看子序列的长度或等效地识别它在ABCDABC中的起始位置来识别这两种情况。

显然,你可以在mississippimississipp中找到pim。