对未排序的向量的STL set_union和set_intersection

时间:2014-10-29 14:23:10

标签: c++ stl

下面是我所做的关于集交集和联合测试的代码。当我注释掉sort函数时,我不明白为什么输出不正确。为什么必要的那种?或者我在这里遗漏了什么? 使程序员负责首先对输入进行排序的技术原因是什么?它是否保证排序不会进行两次(如果向量已经排序并且算法再次对其进行排序......)?

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;
void test_vector_union();
void test_vector_intesection();

int main(int i, char * args [])
{
  cout <<endl<< "test union of unsorted vectors {1,4,3,2,0} and {6,10,2,1,4}" << endl;
  test_vector_union();
  cout <<endl<< "test intersection of unsorted vectors {1,4,3,2,0} and {6,10,2,1,4}" <<     endl;
  test_vector_intesection(); 
  return 0;
 }

void test_vector_union(){
 vector<int> x = {1,4,3,2,0};
 vector<int> y= {6,10,2,1,4};
//sort(x.begin(),x.end()); sort(y.begin(),y.end());
vector<int> z ;
set_union(x.begin(),x.end(),y.begin(),y.end(),back_inserter(z));

for (int i:z)
     cout << i <<",";
}

void test_vector_intesection(){
 vector<int> x = {1,4,3,2,0};
 vector<int> y= {6,10,2,1,4};
 //sort(x.begin(),x.end()); sort(y.begin(),y.end());
 vector<int> z ;
 set_intersection(x.begin(),x.end(),y.begin(),y.end(),back_inserter(z));

 for (int i:z)
     cout << i <<",";

}

3 个答案:

答案 0 :(得分:2)

因为std::set_union要求

  

构造一个从d_first开始的排序范围,由一个或两个排序范围[first1,last1]和[first2,last2)中的所有元素组成。

     

1)使用运算符&lt;

预计要分类的两个输入范围      

2)使用给定的比较函数comp

预期要排序

(强调我的)

你不应该在未排序的范围内调用这些算法。

答案 1 :(得分:1)

如果您关心标准中的官方措辞(§25.4.5/ 1):

  

此部分定义排序结构的所有基本集合操作。它们还适用于包含多个等效元素副本的多集(23.4.7)。 set操作的语义通过定义set_union()以包含每个元素的最大出现次数,set_intersection()包含最小值等,以标准方式推广到多个集合。 [强调补充]

该部分包含std::includesstd::set_unionstd::set_intersectionstd::set_differencestd::set_symmetric_difference的规范,因此对排序输入的要求适用于所有这些算法。

答案 2 :(得分:0)

这是必需的。这是摘自std :: union的文档。: -

Constructs a sorted range beginning at d_first consisting of all elements present in one or both sorted ranges [first1, last1) and [first2, last2).
1) Expects both input ranges to be sorted with operator<
2) Expects them to be sorted with the given comparison function comp
If some element is found m times in [first1, last1) and n times in [first2, last2), then all m elements will be copied from [first1, last1) to d_first, preserving order, and then exactly std::max(n-m, 0) elements will be copied from [first2, last2) to d_first, also preserving order.