具有重复值的Set_Intersection

时间:2017-11-23 22:20:26

标签: c++ stl intersection

我认为这里描述了set_intersection STL函数:http://www.cplusplus.com/reference/algorithm/set_intersection/ 在数学意义上并不是真正的集合交集。假设给出的示例我改变了行:

int first[] = {5,10,15,20,20,25};
int second[] = {50,40,30,20,10,20};

我希望得到10 20 20。但我只能得到独特的答案。 STL中是否存在真正的集合交集?

我知道可以使用merges和set_differences,btw的组合。只是检查我是否遗漏了一些明显的东西。

2 个答案:

答案 0 :(得分:1)

set_intersection要求对两个范围进行排序。在您提供的数据中,second未排序。

如果您先排序,您应该得到预期的答案。

答案 1 :(得分:1)

  

我希望得到10 20 20。但我只能得到独特的答案。 STL中是否存在真正的集合交集?

std::set_intersection可以满足您的需求。

您可能得错了答案,因为您没有正确更新代码。如果将集合更改为包含6个元素,则需要更新对其进行排序的行:

std::sort (first,first+5);   // should be first+6
std::sort (second,second+5); // should be second+6

并将来电更改为set_intersection以使用first+6second+6。否则,您只对每组中的前5个元素进行排序,并且只获得前5个元素的交集。

显然,如果您没有在输入中包含重复值,它将不在输出中。如果您正确更改代码以包含所有输入值,它将按您的需要工作(live example)。

cplusplus.com不是一个很好的参考,如果你看一下http://en.cppreference.com/w/cpp/algorithm/set_intersection,你会看到它清楚地说明重复元素的行为:

  

如果在[first1,last1]中找到一些元素,在[first2,last2]中找到n次,则第一个std::min(m, n)元素将从第一个范围复制到目标范围。

即使cplusplus.com上的例子很糟糕,如果它是用惯用的现代C ++编写的,它会更简单,更难以介绍你的bug:

#include <iostream>     // std::cout
#include <algorithm>    // std::set_intersection, std::sort
#include <vector>       // std::vector

int main () {
  int first[] = {5,10,15,20,20,25};
  int second[] = {50,40,30,20,10,20};

  std::sort(std::begin(first), std::end(first));
  std::sort(std::begin(second), std::end(second));

  std::vector<int> v;
  std::set_intersection(std::begin(first), std::end(first),
                        std::begin(second), std::end(second),
                        std::back_inserter(v));                                               

  std::cout << "The intersection has " << v.size() << " elements:\n";
  for (auto i : v)
    std::cout << ' ' << i;
  std::cout << '\n';
}

这会自动处理正确数量的元素,无需明确说出56或任何其他幻数,也无需在输出向量中创建初始元素然后调整大小再次删除它们。