问题
Below is my code on set intersection and union test that I did. I don't understand why it the output is incorrect when I commented out the sort function. Why is the sort necessary? or am I missing anything here? What is the technical reason for making the programmer responsible to sort the inputs first? Is it for guaranteeing sorting is not done twice(if the vector was already sorted and the algorithm sorts it again...)?
#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 <<",";
}
回答1:
Because it is a requirement for std::set_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
(emphasis mine)
you shouldn't call these algorithms on unsorted ranges.
回答2:
In case you care about the official wording from the standard (§25.4.5/1):
This section defines all the basic set operations on sorted structures. They also work with multisets (23.4.7) containing multiple copies of equivalent elements. The semantics of the set operations are generalized to multisets in a standard way by defining set_union() to contain the maximum number of occurrences of every element, set_intersection() to contain the minimum, and so on. [emphasis added]
That section includes the specifications for std::includes
, std::set_union
, std::set_intersection
, std::set_difference
, and std::set_symmetric_difference
, so the requirement for sorted inputs applies to all of these algorithms.
回答3:
That's required. This is excerpt from documentation of 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.
来源:https://stackoverflow.com/questions/26632809/stl-set-union-and-set-intersection-on-unsorted-vectors