[英]Curious question : What algorithm does STL set_intersect implement?
我花了很多时间在Baeza-Yates的快速设置交集算法中为我的一个应用程序编码。 虽然我确实略微超过了STL set_intersect,但我对输出排序后,从实现自己的算法中获得的任何时间都消除了我要求对结果集进行排序的事实。 鉴于STL set_intersect可以很好地执行此操作,请问有人可以指出它实际实现的算法吗? 还是仅以更有效的方式实现相同的Baeza-Yates算法?
Baeza-Yates: http : //citeseerx.ist.psu.edu/viewdoc/download? doi = 10.1.1.91.7899&rep = rep1&type = pdf
STL不需要任何特定的算法,它只是对某些操作的算法复杂性设置了约束。 由于它们都是基于模板的,因此您可以轻松查看特定实现的源代码以了解其工作原理。
至少在我看过的实现中,实现是相当简单的-按一般顺序进行:
template <class inIt, class outIt>
outIt set_intersection(inIt start1, inIt end1, inIt start2, inIt end2, outIt out) {
while (start1 != end1 && start2 != end2) {
if (*start1 < *start2)
++start1;
else if (*start2 < *start1)
++start2;
else { // equal elements.
*out++ = *start1;
++start1;
++start2;
}
}
return out;
}
当然,我只是在脑海中打了个打字,它甚至可能不会编译,并且肯定也不是正确的(例如,应该使用比较器函数而不是直接使用operator<
,并且应该具有另一个模板参数,以允许start1 / end1与start2 / end2不同。
但是,从算法的角度来看,我猜想大多数实际的实现都和上面的差不多。
有趣。 因此,算法中比较的数量与两个集合中元素的数量呈线性比例关系。 Baeza-Yates算法类似这样(请注意,它假定两个输入集都已排序):
1)找到集合A的中位数(A是这里的较小集合)2)在B中搜索A的中位数。如果找到,将其添加到结果中,否则,已知B中位数的插入等级。 3)将集合A的中位数分为两部分,并将集合B的插入等级分为两部分,然后对这两个部分递归重复该过程。 此步骤之所以有效,是因为所有小于A中位数的元素都只会与A在B中位数的插入等级之前的那些元素相交。
显然,由于您可以使用二进制搜索在B中定位A的中位数,因此该算法中的比较次数比您提到的要少。 实际上,在“最佳”情况下,比较次数为O(log(m)* log(n)),其中m和n是集合的大小,在最坏情况下,比较次数为O(m + n)。 我到底是怎么弄糟这种糟糕的实现的呢? :(
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.