Algorithm 删除内存有限的重复字符串

Algorithm 删除内存有限的重复字符串,algorithm,data-structures,Algorithm,Data Structures,假设我们有一个字符串列表,不能将整个列表加载到内存中,但可以从文件中加载部分列表。解决这一问题的最佳方法是什么?一种方法是对文件进行排序,然后在排序列表上通过一次迭代删除重复项。这种方法只需要很少的额外空间和O(nlogn)对磁盘的访问 另一种方法基于哈希:使用字符串的哈希代码,并加载包含哈希代码位于特定范围内的所有字符串的子列表。可以保证,如果装载了x,并且有一个副本,则该副本也将装载到同一个存储桶中。 这需要O(n*#bucket)访问磁盘,但可能需要更多内存。如果需要,您可以递归调用该过程

假设我们有一个字符串列表,不能将整个列表加载到内存中,但可以从文件中加载部分列表。解决这一问题的最佳方法是什么?

一种方法是对文件进行排序,然后在排序列表上通过一次迭代删除重复项。这种方法只需要很少的额外空间和
O(nlogn)
对磁盘的访问

另一种方法基于哈希:使用字符串的哈希代码,并加载包含哈希代码位于特定范围内的所有字符串的子列表。可以保证,如果装载了
x
,并且有一个副本,则该副本也将装载到同一个存储桶中。

这需要
O(n*#bucket)
访问磁盘,但可能需要更多内存。如果需要,您可以递归调用该过程(使用不同的哈希函数)。

我的解决方案是进行合并排序,这样可以使用外部内存。排序之后,搜索重复项将像只比较两个元素一样简单

例如:

0:猫 1:狗 2:鸟 3:猫 4:大象 5:猫

合并排序

0:鸟 1:猫 2:猫 3:猫 4:狗 5:大象

然后简单地比较0&1->无重复项,继续前进。 1&2->duplicate,remove 1(这可能很简单,只需用空字符串填充它,以便稍后跳过) 比较2和3->删除2 等等


删除1&2而不是2&3的原因是它允许更有效的比较——您不必担心跳过已删除的索引。

文件有多大?你的记忆力有什么限制?目标机器和语言是什么?什么样的弦?他们要多久?预计有多少个副本?如果允许使用外部工具,GNU/Linux
sort
程序可以对大于内存的文件进行排序,并删除副本。如果文件已经排序,请参阅
uniq
程序。@0xbe5077ed:这个广泛问题的一个具体情况是:在外部排序中,您可以在算法的第二次(即合并)过程中删除重复项。@JimMischel:删除pass1中批次中的重复项可以减少批次,保存合并工作。在读取输入时,还可以通过构建一个Trie,甚至是一个DAWG来对更大的pass1批进行排序,以紧凑地表示到目前为止看到的字符串集(在过程中查找重复项)。请看我的答案