从非常大的文本文件中删除重复的字符串

时间:2012-03-22 03:50:44

标签: c# string duplicates

我必须从极大的文本文件(100 Gb +)中删除重复的字符串

因为在内存中由于数据的大小,重复删除是没有希望的,所以我尝试过bloomfilter但是除了5000万字符串之外没有用。

总字符串类似于1万亿+

我想知道解决这个问题的方法是什么。

我最初的尝试是,将文件分成子文件数,对每个文件进行排序,然后将所有文件合并在一起......

如果你有更好的解决方案,请告诉我,

谢谢..

2 个答案:

答案 0 :(得分:3)

您在这里寻找的关键概念是external sorting。您应该能够使用该文章中描述的技术合并整个文件的排序,然后按顺序运行它以删除重复项。

如果文章不够清楚,请查看引用的实现,例如this one

答案 1 :(得分:1)

你可以制作第二个文件,其中包含记录,每个记录是64位CRC加上字符串和文件的偏移量应该被索引以便快速搜索。 像这样:

ReadFromSourceAndSort()
{
   offset=0;
   while(!EOF)
   {
      string = ReadFromFile();
      crc64 = crc64(string);
      if(lookUpInCache(crc64))
      {
         skip;
      } else {
         WriteToCacheFile(crc64, offset);
         WriteToOutput(string);
      }
   }
}

如何制作好的缓存文件?它应按CRC64排序以快速搜索。所以你应该像二进制搜索树那样制作这个文件的结构,但是快速添加新项目而不移动文件中存在的文件。要提高速度,您需要使用Memory Mapped Files

可能的答案:

memory = ReserveMemory(100 Mb);
mapfile= MapMemoryToFile(memory, "\\temp\\map.tmp"); (File can be bigger, Mapping is just window)
currentWindowNumber = 0;

while(!EndOfFile)
{
  ReadFromSourceAndSort(); But only for first 100 Mb in memory
  currentWindowNumber++;
  MoveMapping(currentWindowNumber)
}

和功能查找; Shuld不使用映射(因为每个窗口切换节省100 Mb到HDD并加载100 Mb的下一个窗口)。只需寻找CRC64的100Mb树,如果CRC64找到 - >字符串已存储