找到两组最大公共子集的高效算法?

时间:2010-03-09 01:43:27

标签: algorithm set

每个集合包含一堆校验和。例如:
集A:
{
 4445968d0e100ad08323df8c895cea15
 a67f8052594d6ba3f75502c0b91b868f
 07736dde2f8484a4a3af463e05f039e3
 5b1e374ff2ba949ab49870ca24d3163a
}

设置B:
{
 6639e1da308fd7b04b7635a17450df7c
 4445968d0e100ad08323df8c895cea15
 a67f8052594d6ba3f75502c0b91b868f
}

A和B的最大公共子集是:
{
 4445968d0e100ad08323df8c895cea15
 a67f8052594d6ba3f75502c0b91b868f
}

很多这些操作都将被执行,所以我正在寻找一种有效的算法来实现这一目标。 谢谢你的帮助。

4 个答案:

答案 0 :(得分:7)

将其中一个集合放在散列表中并迭代另一个集合,丢弃不在散列中的元素。或者,对两者进行排序并同时迭代它们,如合并排序。

编辑:后一种方法创建一个排序结果。我应该补充说,如果这些集合具有广泛不同的大小并且它们被预先排序(比如因为你正在做一堆交叉),那么你可以通过使用“无界”二进制搜索来实现大幅提升性能。大名单。

答案 1 :(得分:5)

将它们粘贴在散列表中并注意确切的碰撞。

答案 2 :(得分:1)

  1. 将Set A添加到可以查找是否存在校验和的结构中。
  2. 循环集B,检查集合A中是否存在元素,如果存在,则添加到集合C
  3. Set C是您的常用子集。

答案 3 :(得分:0)

  • 从Set A
  • 制作有序矢量/列表A.
  • 从Set B
  • 制作有序矢量/列表B.
  • 迭代有序的A,B在较小的元素上迈出新的一步 - 如果相同,则添加到restult并移动它们。

当订购基础集结构时 - 常见情况是一种树(BST,AVL等), - 那么你需要只执行最后一步

为了使最后一步清楚,这是伪代码:

a = A.begin(); b = B.begin();
while(a!=A.end() && b!=B.end()){
  if(*a==*b){
    results.add(a);
    ++a; ++b;
  } else if(*a < *b) {
    ++a;
  } else {
    ++b;
  }
}