假设我有两套:
A = [1, 3, 5, 7, 9, 11]
和
B = [1, 3, 9, 11, 12, 13, 14]
两个集合都可以是任意的(和不同数量的元素)。
我正在编写一个性能关键型应用程序,它要求我执行搜索以确定两个集合共有的元素数量。我实际上不需要返回匹配项,只需要返回匹配项数。
显然,一种天真的方法会是一种蛮力,但我怀疑这种方法还不是最优的。是否有执行此类操作的算法?
如果有帮助,在所有情况下,集合将由整数组成。
答案 0 :(得分:2)
如果两个集的大小大致相同,那么同步遍历它们(类似于合并排序合并操作)的速度和它一样快。
看看第一个元素 如果它们匹配,则将该元素添加到结果中,然后向前移动两个指针 否则,您将指向最小值的指针向前移动。
一些伪Python:
a = []
b = []
res = []
ai = 0
bi = 0
while ai < len(a) and bi < len(b):
if a[ai] == b[bi]:
res += a[ai]
ai+=1
bi+=1
elif a[ai] < b[bi]:
ai+=1
else:
bi+=1
return res
如果一组明显大于另一组,则可以使用二分搜索从较大的较小的项中查找每个项目。
答案 1 :(得分:1)
这是一个想法(虽然非常高级别的描述)。
顺便说一下,我会冒昧地假设每组中的数字不会出现多次,例如[1,3,5,5,7,7,9,11]不会的地方。
定义两个变量来保存您在每个数组中检查的索引。
从每组的第一个数字开始并比较它们。两种可能的条件:它们相等或者一个比另一个大。
如果它们相等,则计算事件并将两个数组中的指针移动到下一个元素。
如果它们不同,则将较低值的指针移动到数组中的下一个元素并重复该过程(比较两个值)。
当你到达任一数组的最后一个元素时,循环结束。
希望我能够以清晰的方式解释它。
答案 2 :(得分:1)
如果两个集合都已排序,则两个集合中的最小元素要么是第一个集合的最小值,要么是第二个集合的最小值。如果它是第一组的最小值,则下一个最小元素是第二组的最小值或第一组的第二个最小值。如果你重复这个直到两组结束你已经订购了两套。对于您的具体问题,您只需要比较元素是否也等于。
您可以使用以下算法迭代两个集合的并集:
intersection_set_cardinality(s1, s2)
{
iterator i = begin(s1);
iterator j = begin(s2);
count = 0;
while(i != end(s1) && j != end(s2))
{
if(elt(i) == elt(j))
{
count = count + 1;
i = i + 1;
j = j + 1;
}
else if(elt(i) < elt(j))
{
i = i + 1;
}
else
{
j = j + 1;
}
}
return count
}