【发布时间】:2013-07-22 14:59:46
【问题描述】:
我有一个数据池 (X1..XN),我想为其找到相等值的组。比较非常昂贵,我无法将所有数据都保存在内存中。
我需要的结果是,例如:
X1 等于 X3 和 X6
X2 是唯一的
X4 等于 X5
(行的顺序或行内的顺序无关紧要)。
如何通过成对比较来实现它?
这是我目前所拥有的:
比较所有对 (Xi, Xk) 与 i and 利用传递性:如果我已经找到 X1==X3 和 X1==X6,我不需要比较 X 3 和 X6。
所以我可以使用以下数据结构:
map: index --> group
multimap: group --> indices
其中组是任意分配的(例如输出中的“行号”)。
对于具有 i i, Xk) 对:
如果 i 和 k 都已经分配了一个组,则跳过
-
如果它们比较相等:
- 如果我已经分配了一个组,请将 k 放入该组
- 否则,为 i 创建一个新组并将 k 放入其中
-
如果它们不相等:
- 如果我还没有分配组,请为 i 分配一个新组
- k 也一样
如果我对项目的顺序很小心,那 应该 工作,但我想知道这是否是解决这个问题的最佳/最不令人惊讶的方法,因为这个问题似乎有些普遍。
背景/更多信息:目的是对项目的存储进行重复数据删除。他们已经有一个哈希值,如果发生冲突,我们希望保证完全比较。相关数据的大小具有非常尖锐的长尾分布。
迭代算法(找到任意两个重复项,共享它们,重复直到没有重复项)可能更容易,但我们需要非修改诊断。 代码库是 C++,与 STL / boost 容器或算法一起工作的东西会很好。
[edit] 关于散列:为了这个问题,请假设一个无法替换的弱散列函数。
这是对现有数据进行一次性重复数据删除所必需的,并且需要处理哈希冲突。最初的选择是“快速散列,并在碰撞时比较”,选择的散列有点弱,但改变它会破坏向后兼容性。即便如此,我还是用一个简单的语句睡得更好:如果发生碰撞,您不会得到错误的数据。 而不是写关于 wolf attacks 的博客。
【问题讨论】:
-
使用一个好的散列函数,碰撞的概率大约为零,所以你应该只担心所有项目相等的常见情况。
-
“一次性...向后兼容”这没有意义。
-
@DavidEisenstat:这是一个信任问题,而不是概率问题。万亿分之一的碰撞造成的直接损害可能可以忽略不计,让客户相信这是完全不同的事情。
-
@DavidEisenstat:当前的格式已经允许重复数据删除,但仅在少数“简单”的情况下才可以。对于大多数用户来说,这将是一次透明的维护操作——除非他们经常在新旧版本之间切换。
-
我并不是建议您可以省略昂贵的检查,只是在加密哈希比较相等之后对其进行优化可能是浪费时间,除了非“狼攻击”情况。
标签: c++ algorithm language-agnostic deduplication