我有一个包含连接字符串的文件。
find_or_add(string)
:
伪代码:
file.init() // file == ""
file.find_or_add("cat") // file == "cat", returns 0
file.find_or_add("able") // file == "catable", returns 3
file.find_or_add("table") // file == "catable", returns 2
file.find_or_add("tables") // file == "catables", returns 2
file.find_or_add("spigot") // file == "catablespigot", returns 7
file.find_or_add("pig") // file == "catablespigot", returns 8
我应该在什么算法/结构中查看“汇总”此文件在内存中,并允许最多O(log N)所需的操作?
假设文件大于RAM。
语言并不重要,但我可以阅读Pseudocode,C,Java,Python,Javascript和Haskell。
答案 0 :(得分:1)
如果您的插入很小,那么您可以构建后缀树或后缀数组(使用延迟实现)。由于插入物是< k你只需要将树构建到那个深度,结构只会占用有限的内存。
编辑:如果你必须存储后缀ids(=整数),如果不幸的话,它将不适合内存
后缀树(或更紧凑的后缀数组)然后表示文本的所有子字符串,然后您可以进行简单的查找:
树中的子字符串是什么?
是 - >返回后缀(位于树的叶子中)。
否 - >添加它并将文本附加到源文件中。
我愿意深入研究这个问题,但我必须首先了解模式大小。
编辑:请注意,插入只需要O(k)时间!
EDIT2:如果模式的长度没有限制,那么你可能需要构建一个空间和时间为O(N)的完整树,问题是你通常有一个因子>然后是10bytes / char。 此致,
答案 1 :(得分:1)
后缀数组和后缀树可能会导致内存问题。 (它们总是比文本大,即使你在某个深度切割它们,因为你需要在结构中存储所有后缀ID)。
您可以创建一组代表某些前缀ID的文件。假设我们将所有长度为2的前缀存储在不同的文件中并保持排序。该文件平均包含后缀ID的1/26 ^ 2。所以我们有一个文件aa.txt,ab.txt等堡垒。我们保持排序的文件中的条目(后缀数组)。每次要进行查找时,都要使用加载这个已经排序和检查的小文件。复杂性将是O(N)(您必须加载文件,该文件是文本的恒定可控部分),但您可以调整前因子以获得最佳性能。在5 Gb文件中,例如,如果你使用长度2前缀,那么你将有一组8 Mb大小的文件,对于prefixLength 3你将是大约320 kb所以堡垒..
答案 2 :(得分:0)
可能这不适用,但是this technology and algorithm具有O(log N)搜索,快速插入并且针对具有大型数据集的高效IO进行了大量优化。我可能错了,但在插入和搜索之间感觉很平衡。你觉得怎么样?