是否有支持这些字符串操作的“字符串堆栈”数据结构?


28

我正在寻找一种数据结构,该结构可在字符集上存储一组字符串,该字符集能够执行以下操作。我们将为存储字符串集合的数据结构。DS SΣD(S)S

  • Add-Prefix-Set在:给定一组(可能为空)字符串,其大小由一个常数限制,而字符串长度由一个常数限制,则返回。这两个边界常量都是全局的:对于所有输入它们都是相同的。Ť d{ 小号|Ť 小号小号} ŤD(S)TD({ts | tT,sS})T
  • Get-Prefixes在:返回。请注意,只要我可以在时间内枚举其内容,我就不介意此集合使用什么结构。{ a | 一个小号小号一个Σ } Ö |Σ |D(S){a | asS,aΣ}O(|Σ|)
  • Remove-PrefixesD(S):返回D({s | asS,aΣ})
  • Merge:给定D(S)D(T),返回D(ST)

现在,我真的很想在O(1)时间内进行所有这些操作,但是我对在o(n)时间内进行所有这些操作的结构很好,其中n是最长字符串的长度。结构体。在合并的情况下,我想一个o(n1+n2)运行时间,其中n1n用于第一和n2n为第二结构。

另一个要求是该结构是不可变的,或者至少上述操作返回“新”结构,以使指向旧结构的指针仍然像以前一样起作用。

关于摊销的注释:很好,但是您必须提防持久性。当我一直在重复使用旧结构时,如果在同一结构上使用某些特定的操作集遇到最坏的情况(这会忽略它创建的新结构),我会遇到麻烦。

我想在正在使用的解析算法中使用这种结构;上面的结构将保持算法所需的前瞻性。

我已经考虑过使用trie,但是主要的问题是我不知道如何有效地合并尝试。如果用于的字符串集Add-Prefix-Set仅包含单个字符的字符串,则可以将这些集存储在堆栈中,这将为您提供前三个操作的O(1)运行时间。但是,这种方法也不适用于合并。

最后,请注意,我对因子不感兴趣 :对于我来说,这是不变的。|Σ|


字符串是仅由操作构造的,Add-Prefix-Set还是从任意字符串组开始?
2012年

2
假设在合并操作之前,和中都有一个长度为的字符串。您怎么可能检测到该字符串在时间是否重复?n1=n2STo(n1+n2)
2012年

您可以从其中包含一个单字符字符串的集合开始,但是也可以使用一个空字符串(可以放进Add-Prefix-Set去)
Alex 10 Brink 2012年

@Joe:这是一个好问题-我开始确信合并操作几乎打破了获得这种结构的任何机会……
Alex 10 Brink 2012年

如果您使用“套叠”表示,可以在合并分两叠(n1,n2)

Answers:


5

我考虑了很长时间,但没有发现在类似于Trie的DAG结构中以最愚蠢的方式进行所有操作的问题:

添加前缀集

创建一个特里字符串。将每个叶节点连接到旧Trie的根。T

复杂度:O(|T|)

合并

合并两个结构的根:将所有子节点作为第一个节点的第二个根子节点。现在,您可能有多个标记有来自同一节点的相同字符的边。

O(1)

根的延迟更新

  1. O(|Σ|)O(1)
  2. O(1)

获取前缀

延迟更新根。现在找到根的所有子代,并在到达它们的边上报告字母集。

O(|Σ|)

删除前缀

延迟更新根。合并根的所有子代,并将根指针设置为该单位的结果。延迟更新新的根目录。

O(|Σ|)

坚持不懈

O(1)O(|Σ|)O(logN)N

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.