在文件中找到两行相同的行

时间:2012-12-06 21:31:49

标签: algorithm search

我在亚马逊的采访中被问到这个问题。

你有一个包含许多行的文件,但其中两行是相同的。找到这两行。我给出了在N ^ 2时间内运行的明显答案。然后我想出了一个使用哈希表的答案,但是他们不喜欢这个答案,因为他们说如果文件是千兆字节它就行不通。我想出的另一个答案是,不是将哈希结果存储在内存中,而是创建一个与哈希值同名的文件,并在文件中存储具有相同哈希值的行。要么他们无法理解我的解决方案,要么他们不喜欢它。

有什么想法吗?

由于

3 个答案:

答案 0 :(得分:4)

我可以想到这个问题的两个基本类型的解决方案:

  1. 概率内存解决方案。您可以尝试通过在主内存中存储文件行的摘要来解决此问题。然后,您可以在主内存中进行计算以识别可能的重复项,然后通过回顾磁盘来检查每个可能的重复项。这些解决方案可能是最好的,因为它们具有低内存使用率,高效率和最小化磁盘访问。此类别的解决方案包括

    1. 计算文件每一行的哈希值,然后存储哈希值。任何具有哈希冲突的行都代表一对可能发生碰撞的可能行,并且只能探索这些行。
    2. 使用布隆过滤器存储文件的所有行,然后仅检查在布隆过滤器中发生冲突的对。这实质上是(1)的变体,更节省空间。
  2. 确定性的磁盘解决方案。您可以尝试使用主内存作为临时暂存空间对磁盘上的整个数据集进行计算。这样可以让您在不必将整个文件保存在内存中的情况下获得准确的答案,但除非您稍后进行处理并且可以从重构数据中获益,否则可能会更慢。此类别的解决方案包括

    1. 使用外部排序算法(外部快速排序,外部基数排序等)对文件进行排序,然后线性搜索一对重复元素。
    2. 构建磁盘上的数据结构,如包含所有字符串的B树,然后查询B树。这需要大量的预处理时间,但是对文件的未来操作要快得多。
    3. 将所有内容放入数据库并查询数据库。
  3. 希望这有帮助!

答案 1 :(得分:2)

您可以使用Bloom过滤器:

http://en.wikipedia.org/wiki/Bloom_filter

然后你可以检测(几乎没有误报)重复的行然后存储在内存中,然后再次浏览文件。

两次通过文件,内存使用量非常少,漂亮

答案 2 :(得分:0)

遍历线并计算每条线的长度。你最终会得到类似的东西:

0: 4  
1: 6  
2: 10  
3: 4  
....  

仅比较具有相同长度的thoose线。使用这样的索引可以进一步优化(例如,不将所有内容存储在平面数组中,而是存储在某种树中,或者其他任何内容中。)

顺便说一下,由于性能原因,您对文件的第二个想法可能会被拒绝。使用硬盘频繁随机IO通常是个坏主意:尝试尽可能多地存储在内存中。