泛型算法:有序集合set_union和set_intersection

本文详细解析了C++标准库中set_union与set_intersection函数的使用方法,包括参数说明、返回值、注意事项等,并通过实例展示了如何正确使用这些函数来处理集合运算。

一 常犯的错误

 

請問各位高手
下面的set_union 是哪弄錯了嗎
為啥我一執行就會出現錯誤訊息

vector<int> a,b,c;
for(int i= 0; i < 9; i++)
{
   a.push_back(e);
   b.push_back(e+6);
}
vector<int>::iterator reas;
reas = set_union(a.begin(),a.end(),b.begin(),b.end(),c.begin());
出現的錯誤訊息是
Segmentation fault <core dumped>
麻煩大家了... 謝謝^^

set_union() set_intersection() 最後一個參數是OutIter 型態
妳需要用所謂 Iterator Adaptor 去寫入妳要放的container
front_inserter(),inserter()back_inserter()
不能直接用該containeriterator 去接
以後看到OutIter 這種東西的就考慮使用Iterator Adaptor
以下是小範例
:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef vector<int> Vec;

typedef Vec::iterator VecIter;
void print(const char* name, const Vec& v);
int main(){
     Vec a, b;
     for (Vec::size_type i = 1; i < 7; ++i)
        a.push_back(i);
     for (Vec::size_type i = 4; i < 10; ++i)
        b.push_back(i);
     print("a", a);
       

     print("b", b);
     Vec u;
     set_union (a.begin(), a.end(), b.begin(), b.end(), back_inserter(u));
     Vec i;
     set_intersection(a.begin(), a.end(), b.begin(), b.end(), back_inserter(i));
     print("u", u);
     print("i", i);
     return 0;
}
void print(const char* name, const Vec& v) {
    cout << name << " : ";
    for (Vec::size_type i = 0; i < v.size(); ++i)
       cout << v[i] << " ";
    cout << endl;
}

執行結果 :
a : 1 2 3 4 5 6
b : 4 5 6 7 8 9
u : 1 2 3 4 5 6 7 8 9
i : 4 5 6

FROM MSDN

Standard C++ Library Reference

set_union

  Unites all of the elements that belong to at least one of two sorted source ranges into a single, sorted destination range, where the ordering criterion may be specified by a binary predicate.

template<class InputIterator1, class InputIterator2, class OutputIterator>

    OutputIterator set_union(

        InputIterator1 _First1 ,

        InputIterator1 _Last1 ,

        InputIterator2 _First2 ,

        InputIterator2 _Last2 ,

        OutputIterator _Result

);

template<class InputIterator1, class InputIterator2, class OutputIterator, class BinaryPredicate>

OutputIterator set_union(

InputIterator1 _First1,

InputIterator1 _Last1,

InputIterator2 _First2,

InputIterator2 _Last2,

OutputIterator _Result,

BinaryPredicate _Comp

);

Parameters

_First1

An input iterator addressing the position of the first element in the first of two sorted source ranges to be united and sorted into a single range representing the union of the two source ranges.

_Last1

An input iterator addressing the position one past the last element in the first of two sorted source ranges to be united and sorted into a single range representing the union of the two source ranges.

_First2

An input iterator addressing the position of the first element in second of two consecutive sorted source ranges to be united and sorted into a single range representing the union of the two source ranges.

_Last2

An input iterator addressing the position one past the last element in second of two consecutive sorted source ranges to be united and sorted into a single range representing the union of the two source ranges.

_Result

An output iterator addressing the position of the first element in the destination range where the two source ranges are to be united into a single sorted range representing the union of the two source ranges.

_Comp

User-defined predicate function object that defines the sense in which one element is greater than another. The binary predicate takes two arguments and should return true when the first element is less than the second element and false otherwise.

Return Value

An output iterator addressing the position one past the last element in the sorted destination range representing the union of the two source ranges.

Remarks

The sorted source ranges referenced must be valid; all pointers must be dereferenceable and within each sequence the last position must be reachable from the first by incrementation.

The destination range should not overlap either of the source ranges and should be large enough to contain the destination range.

The sorted source ranges must each be arranged as a precondition to the application of the merge algorithm in accordance with the same ordering as is to be used by the algorithm to sort the combined ranges.

The operation is stable as the relative order of elements within each range is preserved in the destination range. The source ranges are not modified by the algorithm merge .

The value types of the input iterators need be less-than comparable to be ordered, so that, given two elements, it may be determined either that they are equivalent (in the sense that neither is less than the other) or that one is less than the other. This results in an ordering between the nonequivalent elements. When there are equivalent elements in both source ranges, the elements in the first range precede the elements from the second source range in the destination range. If the source ranges contain duplicates of an element, then the destination range will contain the maximum number of those elements that occur in both source ranges.

 The complexity of the algorithm is linear with at most 2 * ( (_Last1 – _First1 ) – (_Last2 – _First2 ) ) – 1 comparisons.

 set_union has two related forms :

checked_set_union

unchecked_set_union

For information on how these functions behave, see Checked Iterators .

Example

// alg_set_union.cpp
// compile with: /EHsc
#include <vector>
#include <algorithm>
#include <functional>      // For greater<int>( )

#include <iostream>
// Return whether modulus of elem1 is less than modulus of elem2

bool mod_lesser ( int elem1, int elem2 )
{
   if ( elem1 < 0 )

      elem1 = - elem1;
 if ( elem2 < 0 )
      elem2 = - elem2;
   return elem1 < elem2;

}
int main( )
{
   using namespace std;
   vector <int> v1a, v1b, v1 ( 12 );

 vector <int>::iterator Iter1a, Iter1b, Iter1, Result1;
// Constructing vectors v1a & v1b with default less than ordering  int i;
   for ( i = -1 ; i <= 3 ; i++ )
   {
      v1a.push_back(  i );
   }
   int ii;
for ( ii =-3 ; ii <= 1 ; ii++ )
   {
      v1b.push_back(  ii  );
   }
  cout << "Original vector v1a with range sorted by the/n "
        <<  "binary predicate less than is  v1a = ( " ;
   for ( Iter1a = v1a.begin( ) ; Iter1a != v1a.end( ) ; Iter1a++ )
      cout << *Iter1a << " ";
   cout << ")." << endl;
   cout << "Original vector v1b with range sorted by the/n "
        <<  "binary predicate less than is  v1b = ( " ;
   for ( Iter1b = v1b.begin ( ) ; Iter1b != v1b.end ( ) ; Iter1b++ )
      cout << *Iter1b << " ";
   cout << ")." << endl;
   // Constructing vectors v2a & v2b with ranges sorted by greater
   vector <int> v2a ( v1a ) , v2b ( v1b ) , v2 ( v1 );
   vector <int>::iterator Iter2a,  Iter2b, Iter2, Result2;
   sort ( v2a.begin ( ) , v2a.end ( ) , greater<int> ( ) );

   sort ( v2b.begin ( ) , v2b.end ( ) , greater<int> ( ) );
cout << "Original vector v2a with range sorted by the/n "
        <<  "binary predicate greater is   v2a =  ( " ;
   for ( Iter2a = v2a.begin ( ) ; Iter2a != v2a.end ( ) ; Iter2a++ )
      cout << *Iter2a << " ";

   cout << ")." << endl; 
 cout << "Original vector v2b with range sorted by the/n "
        <<  "binary predicate greater is   v2b =  ( " ;
   for ( Iter2b = v2b.begin ( ) ; Iter2b != v2b.end ( ) ; Iter2b++ )
      cout << *Iter2b << " ";
   cout << ")." << endl;
   // Constructing vectors v3a & v3b with ranges sorted by mod_lesser
   vector <int> v3a ( v1a ), v3b ( v1b ) ,  v3 ( v1 );
   vector <int>::iterator Iter3a, Iter3b, Iter3, Result3;
   sort ( v3a.begin ( ) , v3a.end ( ) , mod_lesser );

   sort ( v3b.begin ( ) , v3b.end ( ) , mod_lesser  );
   cout << "Original vector v3a with range sorted by the/n "
        <<  "binary predicate mod_lesser is   v3a =  ( " ;
   for ( Iter3a = v3a.begin ( ) ; Iter3a != v3a.end ( ) ; Iter3a++ )
      cout << *Iter3a << " ";
      cout << ")." << endl;
   cout << "Original vector v3b with range sorted by the/n "
        <<  "binary predicate mod_lesser is   v3b =  ( " ;
   for ( Iter3b = v3b.begin ( ) ; Iter3b != v3b.end ( ) ; Iter3b++ )
      cout << *Iter3b << " ";
   cout << ")." << endl;
   // To combine into a union in ascending order with the default
    // binary predicate less <int> ( )
   Result1 = set_union ( v1a.begin ( ) , v1a.end ( ) ,
      v1b.begin ( ) , v1b.end ( ) , v1.begin ( ) );
   cout << "Union of source ranges with default order,"
        << "/n vector v1mod =  ( " ;
   for ( Iter1 = v1.begin( ) ; Iter1 != Result1 ; Iter1++ )
      cout << *Iter1 << " ";
   cout << ")." << endl;
   // To combine into a union in descending order, specify binary
   // predicate greater<int>( )
   Result2 = set_union (  v2a.begin ( ) , v2a.end ( ) ,
      v2b.begin ( ) , v2b.end ( ) ,v2.begin ( ) , greater <int> ( ) );
   cout << "Union of source ranges with binary predicate greater "
        << "specified,/n vector v2mod  = ( " ;
   for ( Iter2 = v2.begin( ) ; Iter2 != Result2 ; Iter2++ )
      cout << *Iter2 << " ";
   cout << ")." << endl;
   // To combine into a union applying a user-defined
   // binary predicate mod_lesser
   Result3 = set_union (v3a.begin(), v3a.end(),

v3b.begin(), v3b.end(), v3.begin(), mod_lesser);
   cout << "Union of source ranges with binary predicate "
        << "mod_lesser specified,/n vector v3mod  = ( " ;

for ( Iter3 = v3.begin( ) ; Iter3 != Result3 ; Iter3++ )
     cout << *Iter3 << " ";
   cout << ")." << endl;
}

Output

Original vector v1a with range sorted by the binary predicate less than is  v1a = ( -1 0 1 2 3 ).


Original vector v1b with range sorted by the binary predicate less than is
v1b = ( -3 -2 -1 0 1 ).
Original vector v2a with range sorted by the binary predicate greater is  v2a =  ( 3 2 1 0 -1 ).
Original vector v2b with range sorted by the binary predicate greater is   v2b =  ( 1 0 -1 -2 -3 ).
Original vector v3a with range sorted by the binary predicate mod_lesser is  v3a =  ( 0 -1 1 2 3 ).
Original vector v3b with range sorted by the binary predicate mod_lesser is   v3b =  ( 0 -1 1 -2 -3 ).

Union of source ranges with default order, vector v1mod =  ( -3 -2 -1 0 1 2 3 ).
Union of source ranges with binary predicate greater specified, vector v2mod  = ( 3 2 1 0 -1 -2 -3 ).
Union of source ranges with binary predicate mod_lesser specified, vector v3mod  = ( 0 -1 1 2 3 ).

set_intersection

  Unites all of the elements that belong to both sorted source ranges into a single, sorted destination range, where the ordering criterion may be specified by a binary predicate.

template<class InputIterator1, class InputIterator2, class OutputIterator>

    OutputIterator set_intersection(

        InputIterator1 _First1 ,

        InputIterator1 _Last1,

        InputIterator2 _First2 ,

        InputIterator2 _Last2 ,

        OutputIterator _Result

);

template<class InputIterator1, class InputIterator2, class OutputIterator, class BinaryPredicate>

OutputIterator set_ intersection (

InputIterator1 _First1 ,

InputIterator1 _Last1 ,

InputIterator2 _First2,

InputIterator2 _Last2,

OutputIterator _Result,

BinaryPredicate _Comp

);

Parameters

_First1

An input iterator addressing the position of the first element in the first of two sorted source ranges to be united and sorted into a single range representing the intersection of the two source ranges.

_Last1

An input iterator addressing the position one past the last element in the first of two sorted source ranges to be united and sorted into a single range representing the intersection of the two source ranges.

_First2

An input iterator addressing the position of the first element in second of two consecutive sorted source ranges to be united and sorted into a single range representing the intersection of the two source ranges.

_Last2

An input iterator addressing the position one past the last element in second of two consecutive sorted source ranges to be united and sorted into a single range representing the intersection of the two source ranges.

_Result

An output iterator addressing the position of the first element in the destination range where the two source ranges are to be united into a single sorted range representing the intersection of the two source ranges.

_Comp

User-defined predicate function object that defines the sense in which one element is greater than another. The binary predicate takes two arguments and should return true when the first element is less than the second element and false otherwise.

Return Value

An output iterator addressing the position one past the last element in the sorted destination range representing the intersection of the two source ranges.

Remarks

The sorted source ranges referenced must be valid; all pointers must be dereferenceable and within each sequence the last position must be reachable from the first by incrementation.

The destination range should not overlap either of the source ranges and should be large enough to contain the destination range.

The sorted source ranges must each be arranged as a precondition to the application of the merge algorithm in accordance with the same ordering as is to be used by the algorithm to sort the combined ranges.

The operation is stable as the relative order of elements within each range is preserved in the destination range. The source ranges are not modified by the algorithm.

The value types of the input iterators need be less-than comparable to be ordered, so that, given two elements, it may be determined either that they are equivalent (in the sense that neither is less than the other) or that one is less than the other. This results in an ordering between the nonequivalent elements. When there are equivalent elements in both source ranges, the elements in the first range precede the elements from the second source range in the destination range. If the source ranges contain duplicates of an element, then the destination range will contain the maximum number of those elements that occur in both source ranges.

The complexity of the algorithm is linear with at most 2 * ( (_Last1 – _First1 ) + (_Last2 – _First2 ) ) – 1 comparisons for nonempty source ranges.

set_intersection has two related forms:

checked_set_intersection

unchecked_set_intersection

For information on how these functions behave, see Checked Iterators .

Example

// alg_set_intersection.cpp
// compile with: /EHsc
#include <vector>
#include <algorithm>
#include <functional>   // For greater<int>( )
#include <iostream>

// Return whether modulus of elem1 is less than modulus of elem2
bool mod_lesser (int elem1, int elem2 )
{

if (elem1 < 0)
     elem1 = - elem1;
 if (elem2 < 0)
      elem2 = - elem2;
   return elem1 < elem2;
}

int main()
{
   using namespace std;
   vector <int> v1a, v1b, v1 (12);
   vector <int>::iterator Iter1a,  Iter1b, Iter1, Result1;

  // Constructing vectors v1a & v1b with default less than ordering
   int i;
  for (i = -1; i <= 3; i++)
      v1a.push_back(i);

   int ii;
   for (ii =-3; ii <= 1; ii++)
      v1b.push_back(ii);
   cout << "Original vector v1a with range sorted by the/n "
        <<  "binary predicate less than is  v1a = ( ";
   for (Iter1a = v1a.begin(); Iter1a != v1a.end(); Iter1a++)
      cout << *Iter1a << " ";
   cout << ")." << endl;
   cout << "Original vector v1b with range sorted by the/n "
        <<  "binary predicate less than is  v1b = ( ";
   for (Iter1b = v1b.begin(); Iter1b != v1b.end(; Iter1b++)
      cout << *Iter1b << " ";
   cout << ")." << endl;
   // Constructing vectors v2a & v2b with ranges sorted by greater
   vector <int> v2a (v1a) , v2b (v1b) , v2 (v1);
   vector <int>::iterator Iter2a, Iter2b, Iter2, Result2;
   sort (v2a.begin(), v2a.end(), greater<int>());
   sort (v2b.begin(), v2b.end(), greater<int>());

 cout << "Original vector v2a with range sorted by the/n "
        << "binary predicate greater is   v2a =  ( " ;
   for ( Iter2a = v2a.begin ( ) ; Iter2a != v2a.end ( ) ; Iter2a++ )
      cout << *Iter2a << " ";
   cout << ")." << endl;
   cout << "Original vector v2b with range sorted by the/n "
        << "binary predicate greater is   v2b =  ( " ;
   for ( Iter2b = v2b.begin ( ) ; Iter2b != v2b.end ( ) ; Iter2b++ )
cout << *Iter2b << " ";
   cout << ")." << endl;
   // Constructing vectors v3a & v3b with ranges sorted by mod_lesser
   vector <int> v3a ( v1a ), v3b ( v1b ) , v3 ( v1 ); 
 vector <int>::iterator Iter3a,  Iter3b, Iter3, Result3;
   sort ( v3a.begin ( ) , v3a.end ( ) , mod_lesser );
   sort ( v3b.begin ( ) , v3b.end ( ) , mod_lesser );
   cout << "Original vector v3a with range sorted by the/n "
        <<  "binary predicate mod_lesser is   v3a =  ( " ;
   for ( Iter3a = v3a.begin ( ) ; Iter3a != v3a.end ( ) ; Iter3a++ )
      cout << *Iter3a << " ";
   cout << ")." << endl;
   cout << "Original vector v3b with range sorted by the/n "
           <<  "binary predicate mod_lesser is   v3b =  ( " ;
   for ( Iter3b = v3b.begin ( ) ; Iter3b != v3b.end ( ) ; Iter3b++ )
      cout << *Iter3b << " ";
   cout << ")." << endl;
   // To combine into an intersection in asscending order with the
   // default binary predicate less <int> ( )
   Result1 = set_intersection ( v1a.begin ( ) , v1a.end ( ) ,
      v1b.begin ( ) , v1b.end ( ) , v1.begin ( ) );
   cout << "Intersection of source ranges with default order,"
        << "/n vector v1mod =  ( " ;
   for ( Iter1 = v1.begin( ) ; Iter1 != Result1 ; ++Iter1 )
      cout << *Iter1 << " ";
   cout << ")." << endl;
   // To combine into an intersection in descending order, specify
   // binary predicate greater<int>( )
   Result2 = set_intersection ( v2a.begin ( ) , v2a.end ( ) ,
      v2b.begin ( ) , v2b.end ( ) ,v2.begin ( ) , greater <int> ( ) );
   cout << "Intersection of source ranges with binary predicate"
        << " greater specified,/n vector v2mod  = ( " ;
   for ( Iter2 = v2.begin( ) ; Iter2 != Result2 ; ++Iter2 )
      cout << *Iter2 << " ";
   cout << ")." << endl;
   // To combine into an intersection applying a user-defined
   // binary predicate mod_lesser
   Result3 = set_intersection ( v3a.begin ( ) , v3a.end ( ) ,
      v3b.begin ( ) , v3b.end ( ) , v3.begin ( ) , mod_lesser );
   cout << "Intersection of source ranges with binary predicate "
        << "mod_lesser specified,/n vector v3mod  = ( " ;
   for ( Iter3 = v3.begin( ) ; Iter3 != Result3 ; ++Iter3 )
      cout << *Iter3 << " ";
   cout << ")." << endl;
}


Output
Original vector v1a with range sorted by the
 binary predicate less than is  v1a = ( -1 0 1 2 3 ).
Original vector v1b with range sorted by the
 binary predicate less than is  v1b = ( -3 -2 -1 0 1 ).
Original vector v2a with range sorted by the
 binary predicate greater is   v2a =  ( 3 2 1 0 -1 ).
Original vector v2b with range sorted by the
 binary predicate greater is   v2b =  ( 1 0 -1 -2 -3 ).
Original vector v3a with range sorted by the
 binary predicate mod_lesser is   v3a =  ( 0 -1 1 2 3 ).
Original vector v3b with range sorted by the
 binary predicate mod_lesser is   v3b =  ( 0 -1 1 -2 -3 ).
Intersection of source ranges with default order,
 vector v1mod =  ( -1 0 1 ).
Intersection of source ranges with binary predicate greater specified,
 vector v2mod  = ( 1 0 -1 ).
Intersection of source ranges with binary predicate mod_lesser specified,
 vector v3mod  = ( 0 -1 1 2 3 ).

Requirements

Header: <algorithm>

Namespace: std

See Also

Concepts

<algorithm> Members

Standard Template Library



 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值