sorting and removing duplicates from vector

Hi, I understand that the code below sorts the vector and remove the duplicates, but can someone tell me what does the unique method return? I know the erase method erases the starting position to the ending position, but now that there is a unique call in the first argument, I don't understand what is happening except that the vector now have no duplicates, why is that?

1
2
sort( vec.begin(), vec.end() );
vec.erase( unique( vec.begin(), vec.end() ), vec.end() );
Last edited on
unique doesn't remove anything from the vector. unique rearranges the vector so that all the duplicates are at the end of vector, but they're still in there.

what does the unique method return?
unique returns an iterator indicating the position in the vector where those duplicates begin.

Here's an example:

vector before unique: { 3 , 4 , 4 , 5, 5, 5 , 6 , 7 , 7 , 8}
vector after unique: { 3 , 4 , 5 , 6 , 7 , 8 , x , x , x , x}

and the returned value is an iterator indicating that first 'x' value.

All those 'x' values; they're still in the vector. the vector is the same size, all the duplicates have been moved to the end and each of those 'x' values is some duplicate item.

erase is then actually removing items from the vector. In the code above, erase is removing all the duplicate items that were moved to the end of the vector. How does it know where to start? Because it is passed an iterator that unique gave back, indicating where those duplicates begin.
Last edited on
Some variants:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;


template<typename T> vector<T> no_duplicates_unique( vector<T> V )                  // uses std::unique() and sorting
{
   sort( V.begin(), V.end() );
   V.erase( unique( V.begin(), V.end() ), V.end() );
   return V;
}


template<typename T> vector<T> no_duplicates_set_sorted( const vector<T> &V )       // uses std::set<T> and sorting
{
   set<T> S( V.begin(), V.end() );
   return vector<T>( S.begin(), S.end() );
}


template<typename T> vector<T> no_duplicates_set_unsorted( const vector<T> &V )     // uses std::set<T> and not sorting
{
   vector<T> result;
   set<T> S;
   for ( const T &e : V )
   {
      if ( S.insert( e ).second ) result.push_back( e );
   }
   return result;
}


template<typename T> ostream & operator << ( ostream &out, const vector<T> &V )
{
   for ( const T &e : V ) out << e << " ";
   return out;
}


int main()
{
   vector<int> A = { 15, 12, 7, 12, 3, 3, 12, 7, 9, 15 };
   cout << "Original:             " <<                             A   << '\n';
   cout << "Using unique:         " << no_duplicates_unique      ( A ) << '\n';
   cout << "Using set (sorted):   " << no_duplicates_set_sorted  ( A ) << '\n';
   cout << "Using set (unsorted): " << no_duplicates_set_unsorted( A ) << '\n';
}


Original:             15 12 7 12 3 3 12 7 9 15 
Using unique:         3 7 9 12 15 
Using set (sorted):   3 7 9 12 15 
Using set (unsorted): 15 12 7 3 9 
Last edited on
Topic archived. No new replies allowed.