寻找重复项的算法

4

有没有著名的算法可以有效地查找重复项?

例如,假设我有数千张照片,并且这些照片都有唯一的名称。可能存在不同子文件夹中的重复项。使用std::map或任何其他哈希映射是否是一个好主意?


问题可以重新表述为:给定一棵树,找到具有相同数据内容的重复节点? - Shamim Hafiz - MSFT
1
你可以使用 HashMap 非常高效地查找某个值是否已经存储。 - Mark Huk
1
你是在寻找文件名相同但内容不同的两个文件,还是文件名不同但内容完全相同的两个文件? - MK.
2个回答

6
如果你正在处理文件,一个想法是先验证文件的长度,然后仅对具有相同大小的文件生成哈希。
然后只需比较文件的哈希值。如果它们相同,则表示有重复文件。
安全性和准确性之间存在权衡:可能会发生不同的文件具有相同的哈希值。因此,您可以改进解决方案:生成一个简单,快速的哈希以查找重复项。当它们不同时,您有不同的文件。当它们再次相等时,请生成第二个哈希。如果第二个哈希不同,则只是误报。如果它们再次相等,可能您有一个真正的重复文件。
换句话说:
generate file sizes
for each file, verify if there's some with the same size.
if you have any, then generate a fast hash for them.
compare the hashes.
If different, ignore.
If equal: generate a second hash.
Compare.
If different, ignore.
If equal, you have two identical files.

如果大多数文件都不同,为每个文件进行哈希处理将花费太多时间,并且是无用的。


3
如果出现哈希冲突,直接比较文件可能会比为每个文件计算第二个哈希值更容易。尽管如果出现某个n > 2的n元冲突时,计算第二个哈希值可能是一个好主意。 - Ted Hopp
1
哪种比较方法更快?二进制比较还是基于CRC的比较?我认为二进制比较更快,而且还可以并行执行。 - sarat
@Ted Hoop:是的,我认为你可能会有多个碰撞。但你的观点很好:如果只有两个文件碰撞,可以逐字节比较它们。 - woliveirajr
@sarat:如果你需要比较5个文件怎么办?你可以计算5个哈希值并进行比较,或者你需要将A与B、C、D和E进行比较,然后将B与C、D和E进行比较...我认为这会花费更长的时间。@Ted Hoop提出了一个很好的观点,当你只有2个文件时,使用二进制比较可能更快,但是对于更多的文件,它会花费更长的时间。 - woliveirajr
相反,如果大多数文件都是重复的,例如从保留了许多已导入文件的数码相机中导入几个新文件,则进行哈希可能需要太长时间。 - Michael
1
我在fslint(findup)中看到过这个算法。不过我想知道,虽然MD5 + SHA1在<64 + <80位碰撞(<144位)处,那么SHA-2 384(在192位处)即使只有一个哈希,也必须更好,对吗? - Stephen

1

也许你想对每个对象进行哈希,并将哈希值存储在某种表中?要测试重复项,只需在表中快速查找即可。

神秘数据结构???

至于完成此任务的“著名算法”,请参阅MD5


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接