将为您提供文件名列表,并且需要返回一个列表,其中的每个项目都是包含相同内容的文件的列表。值得一提的是这些文件的大小非常大。
例如:
如果我们将列表{"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
哈希码的文件列表,您是否有一种返回所需列表的有效方法?
答案 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))中完成。