【问题标题】:Curious question : What algorithm does STL set_intersect implement?好奇的问题:STL set_intersect 实现了什么算法?
【发布时间】:2010-10-27 04:51:32
【问题描述】:

我在 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

【问题讨论】:

    标签: c++ stl set-intersection


    【解决方案1】:

    STL 不需要任何特定的算法,它只是对某些操作的算法复杂性设置约束。由于它都是基于模板的,因此您可以轻松查看特定实现的源代码以了解其工作原理。

    【讨论】:

    • +1。我开始写一个答案,并复制了这个,但你的答案看起来很好,所以我将它粘贴在这里。具体要求是:“复杂度:最多 2 * ((last1 - first1) + (last2 - first2)) - 1 次比较。”
    • 轻松查看,当然。在你的脑袋爆炸之前了解它是如何工作的?现在情况不同了。
    • @PigBen,如果你对这些事情感到好奇,我认为你的头部爆炸阈值比大多数人都高一点。我自己的门槛比我想要的低很多。
    【解决方案2】:

    至少在我看过的实现中,实现是相当简单的——按照这个一般顺序:

    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&lt;直接,并且应该有另一个模板参数以允许 start1/end1 与 start2/end2 不同)。

    但是,从算法的角度来看,我猜大多数实际的实现都与上面差不多。

    【讨论】:

      【解决方案3】:

      有趣。因此,算法中的比较次数与两组中的元素数量呈线性关系。 Baeza-Yates 算法是这样的(注意它假设两个输入集都是排序的):

      1) 求集合 A 的中位数(这里的 A 是较小的集合) 2) 在 B 中搜索 A 的中位数。 如果找到,添加到结果中 否则,B 中中位数的插入秩是已知的。 3) 将集合 A 的中位数拆分为两部分,将 B 的插入秩集合为两部分,并在两部分上递归地重复该过程。 此步骤有效,因为 A 中所有小于中位数的元素只会与 B 中 A 的中位数插入秩之前的那些元素相交。

      由于您可以使用二分查找来定位 A 在 B 中的中位数,显然该算法中的比较次数比您提到的要低。事实上,在“最好”的情况下,比较的次数是 O(log(m) * log(n)),其中 m 和 n 是集合的大小,而在最坏的情况下,比较的次数是O(m + n)。我到底是怎么把实施搞得这么糟糕的? :(

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-02-15
        • 2011-08-22
        • 1970-01-01
        • 2013-08-27
        • 1970-01-01
        • 1970-01-01
        • 2016-09-20
        相关资源
        最近更新 更多