Algorithm Unique Function - C++ Programming Tutorial
C++ Course / STL Algorithm / Algorithm Unique Function

Algorithm Unique Function

BLUF: Mastering Algorithm Unique Function is a critical step in becoming a proficient C++ developer. This lesson provides a deep dive into the syntax, performance considerations, and real-world applications of this concept.
Key Performance Insight: Algorithm Unique Function

C++ is renowned for its efficiency. Learn how Algorithm Unique Function enables low-level control and high-performance computing in the tutorial below.

C++ Algorithm unique

The unique function in C++ Algorithm is employed to modify a sequence so that every duplicate consecutive element is transformed into a distinct element.

The initial iteration employs the operator== for element comparison, while the subsequent iteration utilizes the provided binary predicate pred.

Syntax

Example

equality (1)	template <class ForwardIterator>
                          ForwardIterator unique (ForwardIterator first, ForwardIterator last);

predicate (2)	template <class ForwardIterator, class BinaryPredicate>
                          ForwardIterator unique (ForwardIterator first, ForwardIterator last,
                          BinaryPredicate pred);

Parameter

A forward iterator indicates the location of the initial element within the range that will undergo duplicate elimination.

The last parameter is a forward iterator that points to the position immediately after the last element in the range that will be scanned for removing duplicates.

A custom predicate function object is defined by the user to specify the criteria for considering two elements within a range as equivalent. A binary predicate operates on two arguments and evaluates to true if the condition is met, and false if it is not.

Return value

A forward iterator pointing to the updated end of the range[first, last) where consecutive duplicates have been eliminated.

Complexity

The complexity increases linearly within the specified range [first, last) by comparing each consecutive pair of elements and executing assignment operations on some of them.

Data races

The elements within the range [first, last) are accessed and can be altered if necessary.

Exception safety

This function throws an exception if any of pred, the element comparisons, the element assignments or the operations on iterator throws an exception.

Note: The invalid parameters cause an undefined behavior.

Example 1

Let's explore a straightforward example to illustrate the functionality of the unique method:

Example

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <cctype>

using namespace std;
 
int main() 
{
    // remove duplicate elements
    vector<int> v{1,2,3,1,2,3,3,4,5,4,5,6,7};
    sort(v.begin(), v.end()); 
    auto last = unique(v.begin(), v.end());
    // v now holds {1 2 3 4 5 6 7 x x x x x x}, where 'x' is indeterminate
    v.erase(last, v.end()); 
    for (int i : v)
      cout << i << " ";
    cout << "\n";
    
    return 0;
}

Output:

Output

1 2 3 4 5 6 7

Example 2

Let's see another simple example:

Example

#include <iostream>     // std::cout
#include <algorithm>    // std::unique, std::distance
#include <vector>       // std::vector

using namespace std;

bool myfunction (int i, int j) {
  return (i==j);
}

int main () {
  int myints[] = {10,20,20,20,30,30,20,20,10};           // 10 20 20 20 30 30 20 20 10
  vector<int> myvector (myints,myints+9);

  // using default comparison:
  vector<int>::iterator it;
  it = unique (myvector.begin(), myvector.end());   // 10 20 30 20 10 ?  ?  ?  ?
                                                         //                ^

  myvector.resize( distance(myvector.begin(),it) ); // 10 20 30 20 10

  // using predicate comparison:
  unique (myvector.begin(), myvector.end(), myfunction);   // (no changes)

  // print out content:
  std::cout << "myvector contains:";
  for (it=myvector.begin(); it!=myvector.end(); ++it)
    cout << ' ' << *it;
  cout << '\n';

  return 0;
}

Output:

Output

myvector contains: 10 20 30 20 10

Example 3

Let's see another simple example:

Example

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

using namespace std;

void print(const char* tag, const vector<int>& v) {
  cout << tag << " : ";
  bool first = true;
  for (int x : v) {
    if (first) {
      first = false;
    }
    else {
      cout << ',';
    }
    cout << x;
  }
  cout << endl;
}

int main() {

  {
    vector<int> v = { 2,5,3,3,1,2,4,2,1,1,4,4,3,3,3 };

    decltype(v)::iterator result = unique(v.begin(), v.end());

    v.erase(result, v.end());

    print("unsorted unique", v);
  }

  {
      vector<int> v = { 2,5,3,3,1,2,4,2,1,1,4,4,3,3,3 };

    sort(v.begin(), v.end());
    decltype(v)::iterator result = unique(v.begin(), v.end());

    v.erase(result, v.end());

    print("sorted unique", v);
  }
}

Output:

Output

unsorted unique : 2,5,3,1,2,4,2,1,4,3
sorted unique : 1,2,3,4,5

Example 4

Let's see another simple example:

Example

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <cctype>

using namespace std;

int main() 
{
    // remove duplicate elements (normal use)
    vector<int> v{1,2,3,1,2,3,3,4,5,4,5,6,7};
    sort(v.begin(), v.end()); // 1 1 2 2 3 3 3 4 4 5 5 6 7 
    auto last = unique(v.begin(), v.end());
    // v now holds {1 2 3 4 5 6 7 x x x x x x}, where 'x' is indeterminate
    v.erase(last, v.end()); 
    for (int i : v)
      cout << i << " ";
    cout << "\n";
 
    // remove consecutive spaces
    string s = "wanna go    to      space?";
    auto end = unique(s.begin(), s.end(), [](char l, char r){
        return isspace(l) && isspace(r) && l == r;
    });
    // s now holds "wanna go to space?xxxxxxxx", where 'x' is indeterminate
    cout << string(s.begin(), end) << '\n';
}

Output:

Output

1 2 3 4 5 6 7 
wanna go to space?

Example 5

Let's see another example:

Example

#include <vector>  
#include <algorithm>  
#include <functional>  
#include <iostream>  
#include <ostream>  
  
using namespace std;  
  
// Return whether modulus of elem1 is equal to modulus of elem2  
bool mod_equal ( int elem1, int elem2 )  
{  
   if ( elem1 < 0 )   
      elem1 = - elem1;  
   if ( elem2 < 0 )   
      elem2 = - elem2;  
   return elem1 == elem2;  
};  
  
int main( )  
{  
   vector <int> v1;  
   vector <int>::iterator v1_Iter1, v1_Iter2, v1_Iter3,  
         v1_NewEnd1, v1_NewEnd2, v1_NewEnd3;  
  
   int i;  
   for ( i = 0 ; i <= 3 ; i++ )  
   {  
      v1.push_back( 5 );  
      v1.push_back( -5 );  
   }  
  
   int ii;  
   for ( ii = 0 ; ii <= 3 ; ii++ )  
   {  
      v1.push_back( 4 );  
   }  
   v1.push_back( 7 );  
  
   cout << "Vector v1 is ( " ;  
   for ( v1_Iter1 = v1.begin( ) ; v1_Iter1 != v1.end( ) ; v1_Iter1++ )  
      cout << *v1_Iter1 << " ";  
   cout << ")." << endl;  
  
   // Remove consecutive duplicates  
   v1_NewEnd1 = unique ( v1.begin ( ) , v1.end ( ) );  
  
   cout << "Removing adjacent duplicates from vector v1 gives\n ( " ;  
   for ( v1_Iter1 = v1.begin( ) ; v1_Iter1 != v1_NewEnd1 ; v1_Iter1++ )  
      cout << *v1_Iter1 << " ";  
   cout << ")." << endl;  
  
   // Remove consecutive duplicates under the binary prediate mod_equals  
   v1_NewEnd2 = unique ( v1.begin ( ) , v1_NewEnd1 , mod_equal );  
  
   cout << "Removing adjacent duplicates from vector v1 under the\n "  
        << " binary predicate mod_equal gives\n ( " ;  
   for ( v1_Iter2 = v1.begin( ) ; v1_Iter2 != v1_NewEnd2 ; v1_Iter2++ )  
      cout << *v1_Iter2 << " ";  
   cout << ")." << endl;  
  
   // Remove elements if preceded by an element that was greater  
   v1_NewEnd3 = unique ( v1.begin ( ) , v1_NewEnd2, greater<int>( ) );  
  
   cout << "Removing adjacent elements satisfying the binary\n "  
        << " predicate mod_equal from vector v1 gives ( " ;  
   for ( v1_Iter3 = v1.begin( ) ; v1_Iter3 != v1_NewEnd3 ; v1_Iter3++ )  
      cout << *v1_Iter3 << " ";  
   cout << ")." << endl;  
   
   return 0;
}

Output:

Output

Vector v1 is ( 5 -5 5 -5 5 -5 5 -5 4 4 4 4 7 ).
Removing adjacent duplicates from vector v1 gives
 ( 5 -5 5 -5 5 -5 5 -5 4 7 ).
Removing adjacent duplicates from vector v1 under the
  binary predicate mod_equal gives
 ( 5 4 7 ).
Removing adjacent elements satisfying the binary
  predicate mod_equal from vector v1 gives ( 5 7 ).

Input Required

This code uses input(). Please provide values below:

Logic Practice
Install Logic Practice
Add to home screen for a faster app-like experience