换档字符串的数据结构

时间:2012-01-20 13:57:15

标签: string data-structures

我们对二进制字符串的数据结构感兴趣。令S = s 1 s 2 .... s m 是大小为m的二进制字符串。 Shift(S,i)是字符串S i空格的循环移位到左侧。也就是说,Shift(S,i)= s i s i + 1 s i + 2 ... s m < /子>取值<子> 1 内容S <子> I-1 。建议支持以下的高效数据结构:

    O(1)中的empy DS的
  1. Init()
  2. Insert(s)在O(| s | ^ 2)
  3. 中将二进制字符串插入DS
  4. Search_cyclic(s)检查O(| s |)中的任何Shift(S,i)是否i
  5. 空间复杂度:O(| S 1 | + | S 2 | + ..... + | S m |)其中S i 是一个,如果m字符串我们已经插入了这么远。

    如果我必须为某些给定i找到Search_cyclic(s,i),使用后缀树并在O(| s |)中遍历它非常简单。但是在Search_cyclic(s)中我们没有给定的i,因此我不知道在给定的复杂性中该怎么做。 OTOH,Insert(s)通常将O(| s |)插入到后缀树中,这里给出O(| s | ^ 2)。

1 个答案:

答案 0 :(得分:0)

所以这是我可以向你提出的解决方案。复杂性甚至低于他们对你的要求,但看起来有点复杂。

您保留所有字符串的数据结构将是Trie甚至是Patricia tree。在每个字符串的树中,您希望在所有可能的移位中插入最小循环移位(即,所有可能的最小字典顺序移位)。您可以在线性时间内计算字符串的最小循环移位,稍后我将给出一个可能的解决方案。暂时让我们假设你可以做到。以下是如何实施所需的操作:

  1. Init() - trie和patricia树的init都是常量 - 这里没问题
  2. 插入 - 您在O(| s |)中计算s的最小循环移位s',然后将其插入O(| s'|)= O(| s |)中的任一数据结构中。 )。这甚至比所需的复杂性更好
  3. Search_cyclic(s) - 再次计算O(| s |)中s的最小循环移位,然后检查Patricia或Trie是否存在字符串,这也是在O(| s |)中完成的
  4. 此外,内存复杂性也是必需的,如果构建Patricia,可能会更低。

    所以剩下的就是如何找到最小的循环移位。既然你提到了后缀树,我希望你知道如何在linear time中构建它。所以诀窍是 - 你将你的字符串s附加到自身(即加倍),然后你为doubled字符串构造一个后缀树。这对于| s |仍然是线性的所以没问题。之后,您所要做的就是在此树中找到长度为n的最小后缀。我认为这并不难 - 从根开始并始终遵循当前节点上的链接,该节点上写有最小的字符串,直到累积的长度超过| s |。由于字符串加倍,您将始终能够遵循最小的字符串链接,直到您至少累积| s |。

    希望这个答案有所帮助。