String 如何在两个非常大的文件中找到公共字符串?
我有两个非常大的文件(而且这两个文件都不能放入内存中)每个文件的每一行都有一个字符串(其中没有空格,长度为99/100/101个字符)。 更新:字符串没有任何排序顺序。String 如何在两个非常大的文件中找到公共字符串?,string,algorithm,file,String,Algorithm,File,我有两个非常大的文件(而且这两个文件都不能放入内存中)每个文件的每一行都有一个字符串(其中没有空格,长度为99/100/101个字符)。 更新:字符串没有任何排序顺序。 更新2:我正在Windows上使用Java 现在我想找出找出两个文件中出现的所有字符串的最佳方法。 我一直在考虑使用外部合并排序对两个文件进行排序,然后进行比较,但我不确定这是否是最好的方法。由于字符串的长度基本相同,我一直在想,为每个字符串计算某种哈希值是否是个好主意,因为这会使字符串之间的比较更容易,但这意味着我必须存储为我
更新2:我正在Windows上使用Java 现在我想找出找出两个文件中出现的所有字符串的最佳方法。 我一直在考虑使用外部合并排序对两个文件进行排序,然后进行比较,但我不确定这是否是最好的方法。由于字符串的长度基本相同,我一直在想,为每个字符串计算某种哈希值是否是个好主意,因为这会使字符串之间的比较更容易,但这意味着我必须存储为我从文件中遇到的字符串计算的哈希值,以便以后与其他字符串进行比较时使用。我无法确定什么才是最好的方法。我想听听你的建议
当您建议解决方案时,还请说明如果有两个以上的文件和字符串出现在所有这些文件和字符串中,那么解决方案是否有效。文件中的数据是否有顺序?我提出这个问题的原因是,尽管逐行比较需要很长时间,但逐行检查一个文件,同时在另一个文件中进行二进制搜索要快得多。但是,这只能在数据以特定方式排序的情况下起作用。我会将这两个文件加载到两个数据库表中,以便文件中的每个字符串都成为表中的一行,并使用SQL查询使用联接查找重复行。您还没有说您使用的是什么平台,因此我假设您使用的是Windows,但是,如果您使用的是Unix平台,那么标准工具将为您完成这项工作
sort file1 | uniq > output
sort file2 | uniq >> output
sort file3 | uniq >> output
...
sort output | uniq -d
我将按如下方式执行(对于任意数量的文件):
- 只对一个文件进行排序
- 浏览下一个文件(#2)的每一行,并对#1文件进行二进制搜索(基于行数)
- 如果你找到了字符串;将其写入另一个临时文件(#temp1)
- 完成#2后,sort#temp1转到#3并执行相同的搜索,但这次是在#temp1上,而不是在#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.
有两个潜在问题
(如果人们想要一个更完整的python实现,那么编写起来相当容易,不过我不懂java!) 根据一个文件中条目的相似程度,可以从中创建(而不是树)。使用这个trie,您可以迭代另一个文件,并检查每个条目是否在trie中
当您有两个以上的文件时,迭代一个文件并根据匹配项构建一个新的trie。这样,您的最后一次trie将包含所有文件中包含的所有匹配项。在windows中执行此操作非常简单。。 假设您有两个文件A和B。“A”文件包含要在文件B中搜索的字符串。只需打开命令提示符并使用以下命令
FINDSTR /G:A B > OUTPUT
这个命令非常快,可以非常有效地比较两个文件。文件输出将包含A和B中常见的字符串
如果要执行OR操作(B中的字符串不是A),请使用
如果您是在Windows平台上,此解决方案的简单性非常好,可能值得寻找Unix设备或安装cygwin。这也是我解决这个问题的方法。这不会告诉所有文件中哪些字符串是重复的,而是输出所有文件的集合并集。uniq-d删除单独出现的行,只打印重复行的一个副本。这确实是最简单的解决方案,即使您必须在windows上安装cygwin(这相对来说比较轻松)。与自己滚动相比,它将节省您很多时间。谢谢您的支持。但我必须在Windows中使用Java来处理这个问题:(只是想知道为什么你关注的是行而不是单词?问题状态是在两个大文件中找到公共字符串(单词)。请给出建议。还有一个问题-需要应用哈希函数吗?我们不能直接将字符串存储为键值吗?
FINDSTR /G:A B > OUTPUT
FINDSTR /V /G:A B > OUTPUT