查找要消除重复的项目
finding items to de-duplicate
我有一个数据池(X1..XN),我想为其查找相等值的组。比较是非常昂贵的,而且我不能把所有的数据都保存在内存中。
例如,我需要的结果是:
X1等于X3和X6
X2是唯一的
X4等于X5
(行的顺序或行内的顺序无关紧要)。
如何通过成对比较实现这一点
到目前为止,我拥有的是:
将所有对(Xi,Xk)与i<k、 和利用传递性:如果我已经找到了X1=X3和X<sub+1>==X6,我就不需要比较X3与X2。
所以我可以使用以下数据结构:
map: index --> group
multimap: group --> indices
其中组是任意分配的(例如输出中的"行号")。
对于具有i<k:
如果i和k都已经分配了一个组,则跳过
如果比较相等:
- 如果我已经分配了一个组,那么把k放在该组中
- 否则,为i创建一个新组,并将k放入其中
如果它们不相等:
- 如果我还没有分配组,请为我分配一个新组
- k相同
如果我仔细处理项目的顺序,应该有效,但我想知道这是否是解决这个问题的最佳/最不令人惊讶的方法,因为这个问题似乎有点常见。
背景/更多信息:目的是消除项目的重复存储。它们已经有了一个散列,在发生冲突的情况下,我们希望保证进行完整的比较。所讨论的数据的大小具有非常尖锐的长尾分布。
迭代算法(找到任意两个重复项,共享它们,重复直到没有重复项为止)可能更容易,但我们希望不修改诊断。代码库是C++,与STL/boost容器或算法配合使用会很好。
[edit]关于哈希:为了这个问题,请假设一个无法替换的弱哈希函数。
这是对现有数据进行一次性重复数据消除所必需的,并且需要处理哈希冲突。最初的选择是"快速哈希,并在碰撞时进行比较",选择的哈希有点弱,但更改它会破坏向后兼容性。即便如此,我还是用一句简单的话睡得更好:如果发生碰撞,你不会得到错误的数据而不是写关于狼袭击的博客。
这里有另一个可能更简单的数据结构,用于利用传递性。制作一个需要进行的比较队列。例如,如果有4个项目,则为[(1,2)、(1,3)、[(1,4)、](2,3)、/(2,4)、.(3,4)]。还有一个数组,用于您已经完成的比较。在每次比较之前,请检查该比较以前是否进行过,每次找到匹配项时,请遍历队列并将匹配项索引替换为其较低的索引。
例如,假设我们弹出(1,2),进行比较,它们不相等,将(1,2-)推到already_visited
的数组中并继续。接下来,弹出(1,3),发现它们是相等的。此时,遍历队列并将所有3个替换为1个。队列将是[(1,4),(2,1),(2,4),[(1,4],依此类推。当我们到达(2,1。
但我同意前面的回答。由于比较在计算上很昂贵,您可能希望首先计算一个快速、可靠的哈希表,然后再将此方法应用于冲突。
所以。。。你已经有哈希了?这个怎么样:
- 哈希排序和分组
- 将尺寸为1的所有组打印为唯一
- 比较碰撞
比较冲突的提示:为什么不用不同的算法重新处理它们呢?冲洗,重复。
(此外,我假设两种不同的哈希算法不会在不同的数据上发生冲突,但这可能是安全的假设…)
对每个项目进行哈希。列出pair<hash,item_index>
。您可以通过按哈希对该列表进行排序或将其放入std::multimap
来查找组。
输出组列表时,需要比较哈希冲突的项。因此,对于每个项目,您将进行一次哈希计算和大约一次比较。以及哈希列表的排序。
我同意使用第二个(希望是改进的)散列函数的想法,这样你就可以解决一些弱散列的冲突,而不需要进行昂贵的成对比较。既然你说你有内存限制问题,希望你能把整个哈希表(带辅助密钥)放在内存中,对于表中的每个条目,你都会为磁盘上对应于该密钥对的记录存储一个记录索引列表。然后问题是,对于每个密钥对,是否可以将所有记录加载到具有该密钥对的内存中。如果是这样的话,那么您就可以对密钥对进行迭代;对于每个密钥对,释放前一个密钥对的内存中的任何记录,并将当前密钥对的记录加载到内存中,然后像您已经概述的那样在这些记录之间进行比较。如果你有一个密钥对,你不能将所有记录都放入内存,那么你必须加载部分子集,但你绝对应该能够在内存中维护你为密钥对找到的所有组(每个组都有一个唯一的记录代表),因为如果你有好的二次哈希,唯一记录的数量就会很小。
- 查找项目在哈希表中的位置
- 如何在Cmake中正确查找头路径,以便在我的项目中构建Box2D
- Visual Studio 2015资源视图和资源编译器使用不同的方法在项目目录中查找图标文件.如何修复
- 在5d映射C++中查找项目
- 通过查找一对项目的代码获取错误的输出,在给定的总和相等的给定列表中列表
- 查找两个 3 位数字的乘积(欧拉项目 #4)
- 更改 std::set 以按 T 类型查找项目
- C 使用字符串项目在列表中查找结构
- unordered_map仅查找先前找到的项目之后的项目
- 使用STD ::查找从向量中选择项目
- STD :: MAP-如何查找或添加,然后可以在一次搜索中删除项目
- 从项目名称查找 API 中查找项目
- 在给定键 (C++) 的地图向量内查找项目
- 如何在助推向量中查找项目
- 如何在 std::vector 中查找项目的位置
- 根据世界位置查找一维数组中的通用项目
- 如何从矢量C++中查找和擦除项目
- 查找 STL 队列中是否已存在项目
- 当我在xcode项目中使用 #include < OpenGL/gl.h>行时,它会在哪里查找gl.h文件?
- 在没有第三方工具/项目的情况下,在 MFC C++发布版本中查找内存泄漏