【问题标题】:Remove of duplicate strings from very big text file从非常大的文本文件中删除重复的字符串
【发布时间】:2012-04-06 15:43:53
【问题描述】:

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

由于数据量大,内存中的重复删除是没有希望的,我尝试了bloomfilter,但除了5000万个字符串之外没有用..

总字符串大约 1 万亿个以上

我想知道有什么方法可以解决这个问题..

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

如果您有比这更好的解决方案,请告诉我,

谢谢..

【问题讨论】:

  • 你在正确的轨道上;基于磁盘的合并排序会为您完成。之后,它只是通过文件的单次传递。
  • 可能所有 CS 学生第一年都会学习一些花哨的算法,但如果我不得不考虑很长时间,我可能会说考虑实现基于磁盘的哈希集之类的东西。为有意义的桶数选择一个值,称之为 n。创建 n 个文件。获取每个字符串的哈希码,并取该值 %n(调用结果 m)查看它属于哪个存储桶。然后检查m对应的文件,看里面是否存在字符串。如果没有,请添加它。移动到下一个字符串。完成此过程后,您可以合并文件。
  • 基本思想是忘记排序。只需创建大量的桶,越大越好,然后扫描桶。
  • 我既不是硬件人,也没有CS背景。就像我说的那样,我完全希望任何真正了解这两者的人都会嘲笑我的建议。幸运的是,我不必在日常工作中删除 100GB 文件中的重复字符串。
  • 其他好奇,多长时间能找到重复项?是经常发生,还是只是一些奇怪的案例,还是真的不为人知?我有一个较小的案例(约 10 个 Go 文件),结果发现大多数相同的消息都聚集在一起,大部分是预先排序的。找到独特的很容易,只需查看下一行,看看是否相同。最后,少数罕见的重复并不重要。

标签: c# string duplicates


【解决方案1】:

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

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

【讨论】:

  • 是的。 CS 基础知识和维基百科的帮助。
【解决方案2】:

您可以制作第二个文件,其中包含记录,每个记录是 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)
}

和函数查找;不应使用映射(因为每个窗口切换都会将 100 Mb 保存到 HDD 并加载下一个窗口的 100 Mb)。只需在 CRC64 的 100Mb 树中寻找,如果找到 CRC64 -> 字符串已存储

【讨论】:

  • 感谢二叉搜索树的想法。我也在验证不同的方法,1)基于磁盘的 Bloom 过滤器(将占用 1 个字节/字符串)2)基于磁盘的 Hashset/SortedSet 基于 .NET Hashset/SortedSet 类 3)外部排序 4)数据库(sqlite /sql server 等)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-06
  • 2015-01-01
  • 1970-01-01
  • 2011-03-16
  • 1970-01-01
相关资源
最近更新 更多