给定文件名列表,返回内容相同的文件列表列表-面试问题

时间:2018-12-15 14:34:38

标签: algorithm performance file

将为您提供文件名列表,并且需要返回一个列表,其中的每个项目都是包含相同内容的文件的列表。值得一提的是这些文件的大小非常大。

例如:
如果我们将列表{"file1", "file2", "file3", "file4", "file5"}作为输入,并且知道file1.content()==file2.content()==file3.content, file4.content==file5.content(), file3.content()!=file4.content(),则输出应为:
 {{"file1", "file2", "file3"}, {"file4", "file5"}}

我对面试官说,我们可以创建HashMap,以其sha512哈希码对文件进行哈希处理。然后,我们可以遍历映射中的键,对于每个键,我们遍历映射到它的列表,以比较列表中的文件对(以检查确实每对文件具有相同的内容)。

此解决方案的唯一问题是,我没有如上所述返回列表列表,而只是返回了一对重复文件。也就是说,对于上面的示例-我返回了此代码:
{{"file1", "file2"}, {"file2", "file3"}, {"file4", "file5"}}

我只是找不到创建所需输出的有效方法。
对于上面的示例,我的HashMap可能(尽管不太可能)只有一个映射到所有输入文件的键。
对于此类情况,我无法找到比最后一次O(n^2)比较(n是列表中的文件数)返回所需列表的算法。

假设您已经准备好将sha512个键的HashMap映射到具有该sha512哈希码的文件列表,您是否有一种返回所需列表的有效方法?

2 个答案:

答案 0 :(得分:1)

因此,您具有文件:“ file1”至“ file5”。假设您为每个对象计算sha512,最终得到以下结果:

 Name                SHA512
file1   000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F
file2   0123456789ABCDEFFEDCBA98765432101963DEADBEEFF00BA977345417B00BE5
file3   000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F
file4   0123456789ABCDEFFEDCBA98765432101963DEADBEEFF00BA977345417B00BE5
file5   000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F

如果按SHA512对列表进行排序,则您可以:

file1   000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F
file3   000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F
file5   000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F
file2   0123456789ABCDEFFEDCBA98765432101963DEADBEEFF00BA977345417B00BE5
file4   0123456789ABCDEFFEDCBA98765432101963DEADBEEFF00BA977345417B00BE5

列表中的文件现在按哈希值分组。遍历列表并输出组是一件微不足道的事情。

正如OP在注释中指出的那样,不能保证两个具有相同SHA512哈希的文件具有相同的内容。因此,在按哈希将文件分组之后,必须将彼此进行比较。

或者,您可以将MD5用作初始哈希,然后按其MD5哈希将文件分组在一起。然后,对于具有相同MD5哈希的文件,请计算SHA512哈希。如果两个文件具有相同的MD5哈希值和相同的SHA512哈希值,则它们不太可能不同。但是,如果要确定,则必须将每个文件与其他文件逐字节进行比较。

答案 1 :(得分:0)

如注释中所述,在散列之前比较文件有一些启发(例如检查文件大小的文件)。顺便说一句,如果给出了每个文件的哈希值,则可以对哈希文件进行排序(在O(n log(n)中),然后遍历哈希并对文件进行存储桶化(在O(n)中),因此可以最坏的情况是在O(n log(n))中完成。