【问题标题】:I want to perform a multi-set intersection using C++我想使用 C++ 执行多集交集
【发布时间】:2017-01-21 17:18:51
【问题描述】:

我正在使用std::set<int> 和多集类std::multiset<int> 执行一些集合操作——联合、交集等。问题是我必须在两个多集之间执行交集,这样我也会得到重复的值.当我将它与简单集合(而不是多集合)一起使用时,交叉点可以正常工作,例如

Set1={1,2,3,4,5,6}
Set2={4,5,6,7,8,9}
那么
std::set_intersection 给我一个正确的结果是 {4,5,6}

但是,如果我有一个多重集

多组1{1,1,2,2,3,3,4,4,5,5,6,6}
多集2{4,4,5,5,6,6,7,7,8,8,9,9}

我再次使用 std::set_intersection 它再次给了我结果 {4,5,6}

这是不正确的,因为实际的交点是{4,4,5,5,6,6}

虽然我使用多重集来保存交集的结果,但我仍然得到错误的答案。

谁能告诉我如何解决这个问题。

【问题讨论】:

  • 作为一种解决方法,您的实现是否允许使用 std::set 向量,然后 set_intersection 将返回包含您需要的所有元素的向量?
  • 那么对于每个{elememt,count},您想要输出中两个多重集之间的最小计数吗?
  • 谢谢,也许每个人都可以使用向量来完成,但我更喜欢使用集合的解决方案,因为它们在我的代码中无处不在。我只想得到我在示例中显示的结果。我不希望重复的元素被视为重复元素,而是一个单独的数字。 @Yakk 是的,就像你刚才说的那样
  • 你一定是做错了什么。 set_intersection 明确指定具有您正在寻找的行为。
  • "构造一个从 d_first 开始的排序范围,包含在排序范围 [first1, last1) 和 [first2, last2) 中找到的元素。如果某个元素在 [first1, last1] 中找到 m 次) 和 [first2, last2) 中的 n 次,第一个 std::min(m, n) 元素将从第一个范围复制到目标范围。保留等效元素的顺序。结果范围不能与任何一个重叠输入范围。”,是的,非常清楚。提供minimal reproducible example

标签: c++ set multiset set-intersection


【解决方案1】:

请您发布您的代码以检查是否有错误? 我编写了一个交叉点示例,如下面的代码,它可以工作。

multiset<int> ms1;
ms1.insert(1);
ms1.insert(1);
ms1.insert(1);
ms1.insert(2);
ms1.insert(3);

multiset<int> ms2;
ms2.insert(1);
ms2.insert(1);
ms2.insert(2);
ms2.insert(2);
ms2.insert(4);

vector<int> v(10);
set_intersection( ms1.begin(), ms1.end(), ms2.begin(), ms2.end(), v.begin() );

结果是 1,1,2。这是正确的!

【讨论】:

  • 尝试在ms2 中添加一个额外的1,看看你会得到什么。
  • @NathanOliver 没有错。还是正确答案。记得将向量 v 的大小增加到 11 :) 好吧,向量的大小必须根据集合的大小。我提交的第一个有错误。
  • 是的。我的错。倒退了
  • @Jamāl 你需要set_intersection( set1.begin(), set1.end(), set2.begin(), set2.end(), vector.begin(), cmpA );
  • @Jamāl 这不是真正调试问题的地方。如果您在使代码正常工作时遇到问题,请提出问题并将其放入 minimal reproducible example
【解决方案2】:

set_intersection 实际上也为多重集执行交集。我假设您对 set_intersection 的调用是错误的。您必须满足的要求很少,请参阅参考资料,例如:

结果范围不能与任一输入范围重叠。

但是,请看下面的代码:

#include <iostream>
#include <iterator> // inserter
#include <algorithm> // set_intersection
#include <set> // multiset

int main() {
    std::multiset<int> set1 = { 1,1,2,2,3,3,4,4,5,5,6,6 };
    std::multiset<int> set2 = { 4,4,5,5,6,6,7,7,8,8,9,9 };
    std::multiset<int> intersection;
    std::set_intersection(set1.begin(), set1.end(), set2.begin(), set2.end(), std::inserter(intersection, intersection.begin()));

    // prints: 4 4 5 5 6 6 
    for(int elem : intersection) {
        std::cout << elem << ' ';
    } 
}

【讨论】:

    猜你喜欢
    • 2015-09-12
    • 2015-07-20
    • 2012-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-04
    • 2017-07-02
    相关资源
    最近更新 更多