Algorithm 使用什么算法删除重复项?
假设我们有一个文件,例如称为“A.txt”。我们知道有一些重复的元素。“A.txt”非常大,比内存大十倍多,可能在50GB左右。有时,B的大小大约等于A的大小,有时比A的大小小很多倍。 让它有这样的结构:Algorithm 使用什么算法删除重复项?,algorithm,duplicates,Algorithm,Duplicates,假设我们有一个文件,例如称为“A.txt”。我们知道有一些重复的元素。“A.txt”非常大,比内存大十倍多,可能在50GB左右。有时,B的大小大约等于A的大小,有时比A的大小小很多倍。 让它有这样的结构: a 1 b 2 c 445 a 1 我们需要得到文件“B.txt”,它不会有这样的副本。例如,它应该是这样的: a 1 b 2 c 445 我考虑了复制A和B的算法,然后取B中的第一个字符串,互相查找,如果找到相同的字符串,则删除重复的字符串。然后取第二个字符串,等等 但我认为它太慢了。我
a 1
b 2
c 445
a 1
我们需要得到文件“B.txt”,它不会有这样的副本。例如,它应该是这样的:
a 1
b 2
c 445
我考虑了复制A和B的算法,然后取B中的第一个字符串,互相查找,如果找到相同的字符串,则删除重复的字符串。然后取第二个字符串,等等
但我认为它太慢了。我能用什么
A是不是数据库!请不要用SQL
对不起,那没有说,分类是可以的
虽然可以排序,但是如果不能排序呢?你基本上必须建立一个可搜索的结果集(如果语言让你想起数据库技术,这不是偶然的,不管你多么讨厌数据库处理与你相同的问题) 其中一种可能的有效数据结构是排序范围(可实现为某种类型的树)或哈希表。因此,在处理文件时,您可以高效地将每个记录插入结果集中,并在该阶段检查结果是否已经存在。完成后,将减少一组唯一记录 结果集也可以存储对任何原始记录的某种引用,而不是复制实际记录。这取决于记录是否足够大,以使其成为更有效的解决方案 或者,您可以简单地在原始数据中添加一个标记,无论是否包含该记录
(也考虑使用一个有效的存储格式,如NETCDF二进制数据,因为文本表示的访问和处理要慢得多)。一个解决方案是对文件进行排序,然后一行一行复制到一个新文件中,过滤出连续的重复。 然后问题变成了:如何对太大而无法放入内存的文件进行排序
给你另请参见。假设您可以将文件的
1/k
部分放入内存,并且仍然有空间用于工作数据结构。整个文件可以在k
或更少的过程中处理,如下所示,这可能比根据行长度和排序算法常数对整个文件进行排序快得多。排序平均值O(n ln)
下面的过程是O(kn)
最坏情况。例如,如果行的平均长度为10个字符,并且有n=5G行,ln(n)~22.3
。此外,如果您的输出文件B
比输入文件A
小得多,则该过程可能只需要一到两次
过程:
1/k
,因此处理最多需要k
次
更新1应使用单独的输出文件p,而不是重复写入和读回已处理的前导行,在每次传递结束时将进程缓冲区R附加到该文件中。当结果文件B几乎与a一样大时,这会将读写量减少一倍
k/2
,或者当B比a小得多时,会减少一点;但它在任何情况下都不会增加I/O量。我认为CouchDB是一种NoSQL解决方案。您说过“a.txt”不适合内存。你知道A的唯一元素(即B中的结果)是否适合存储吗?我想他们不会,但如果他们这样做了,问题就大大简化了。B也不能放在内存中。你有Microsoft Access吗?这可以很容易地在Access中完成,即使使用txt文件也是如此。我需要的是算法,而不是实现。但是,文件的顺序与原始顺序不同。然而,没有-1,因为这可能并不坏。OP应该会告诉你。你可以用行号装饰文件,按你想重复消除的键排序,重复消除,然后按行号重新排序。我喜欢你的算法:)你是数学家吗?这是第一个不太明显的答案:程序员/分析师比数学家多。请随意投票支持我的答案!:)