如何在两个非常大的文件中找到常用字符串?

时间:2009-03-18 13:58:14

标签: string algorithm file

我有两个非常大的文件它们都不适合内存)。 每个文件都有一个字符串(其中没有空格,长度为99/100/101个字符)

更新:字符串不按任何排序顺序排列 Update2:我在Windows上使用Java。

现在我想找出找出两个文件中出现的所有字符串的最佳方法。

我一直在考虑使用外部合并排序来对这两个文件进行排序然后进行比较,但我不确定这是否是最好的方法。由于字符串大多数都是相同的长度,我总是想知道为每个字符串计算某种哈希是否是个好主意,因为这样可以使字符串之间的比较更容易,但那意味着我必须存储哈希值计算我到目前为止从文件中遇到的字符串,以便稍后在将它们与其他字符串进行比较时可以使用它们。我无法确定最佳方式。我正在寻找你的建议。

当您提出解决方案时,如果有超过2个文件并且必须计算出所有文件中的字符串,请说明解决方案是否有效。

8 个答案:

答案 0 :(得分:18)

你还没有说过你正在做什么平台,所以我假设你正在使用Windows,但是在不太可能的情况下,你是在Unix平台上,标准工具会为你做。

sort file1 | uniq > output
sort file2 | uniq >> output
sort file3 | uniq >> output
...
sort output | uniq -d

答案 1 :(得分:3)

我会按照以下方式(对于任意数量的文件)执行此操作:

  • 排序仅1个文件(#1)。
  • 浏览下一个文件的每一行(#2)并对#1文件进行二进制搜索(基于行数)。
  • 如果找到字符串;将其写在另一个临时文件(#temp1)上。
  • 完成#2之后,排序#temp1转到#3并进行相同的搜索,但这次是在#temp1上,而不是#1,这应该比第一个少得多,因为它只有重复的行。< / LI>
  • 使用新的临时文件重复此过程,删除以前的#temp文件。随着重复行数的减少,每次迭代都应该越来越少。

答案 2 :(得分:2)

根据一个文件中条目的相似程度,可以从中创建Trie(非树)。使用此trie,您可以迭代另一个文件并检查每个条目是否在trie中。

当你有两个以上的文件时,迭代一个文件并从匹配中构建一个新的trie。这样,您拥有的最后一个trie将包含所有文件中包含的所有匹配项。

答案 3 :(得分:0)

文件中的数据是否有任何顺序?我问的原因是虽然逐行比较会花费一个永恒,逐行浏览一个文件,而在另一个文件中进行二元搜索会更快。只有在以特定方式对数据进行排序时,这才有效。

答案 4 :(得分:0)

我会将这两个文件加载到两个数据库表中,以便文件中的每个字符串成为表中的一行,并使用SQL查询通过连接查找重复的行。

答案 5 :(得分:0)

我会对每个文件进行排序,然后使用平衡线算法,从一个文件或另一个文件一次读取一行。

答案 6 :(得分:0)

基于散列的解决方案可能如下所示(在python伪代码中):

hashes = dict()
for file in files:
    for line in lines:
        h = md5(line)
        hashes[h] += 1

然后再次循环,打印匹配的行:

for file in files:
    for line in lines:
        h = md5(line)
        if hashes[h] == nfiles:
            print line
            del hashes[h]  # since we only want each once.

有两个潜在的问题。

  1. 潜在的哈希冲突(可以减轻一些,但风险很大。)
  2. 需要能够处理大小的dict(关联数组):|所有文件中的uniq行|
  3. 这是O(行*成本(md5))。

    (如果人们使用更全面的python实现,那么写起来很容易,但我不知道java!)。

答案 7 :(得分:0)

要在Windows中执行,它非常简单.. 比方说,你有两个文件A和B.'A'文件包含你想在文件B中搜索的字符串。只需打开命令提示符并使用以下命令

FINDSTR /G:A B > OUTPUT

这个命令非常快,可以非常有效地比较两个文件。文件OUTPUT将包含A和B中常见的字符串。

如果要执行OR操作(B中除A以外的字符串),请使用

FINDSTR /V /G:A B > OUTPUT