std::unique in C++

25 Jul, 2017
std::unique is used to remove duplicates of any element present consecutively in a range[first, last). It performs this task for all the sub-groups present in the range having the same element present consecutively.
It does not delete all the duplicate elements, but it removes duplicacy by just replacing those elements by the next element present in the sequence which is not duplicate to the current element being replaced. All the elements which are replaced are left in an unspecified state.
Another interesting feature of this function is that it does not changes the size of the container after deleting the elements, it just returns a pointer pointing to the new end of the container, and based upon that we have to resize the container, or remove the garbage elements.
It can be used in two ways as shown below:
Comparing elements using ==:Syntax:template 
ForwardIterator unique (ForwardIterator first, ForwardIterator last);

first: Forward iterator to the first element in the container.
last: forward iterator to the last element in the container.

Return Value: It returns an iterator to the element that follows 
the last element not removed. The range between first and this iterator includes 
all the elements in the sequence that were not
duplicates and hence not removed.
// C++ program to demonstrate the use of std::unique#include <iostream>#include <vector>#include <algorithm>using namespace std;int main(){    vector<int> v = { 1, 1, 3, 3, 3, 10, 1, 3, 3, 7, 7, 8 }, i;      vector<int>::iterator ip;      // Using std::unique    ip = std::unique(v.begin(), v.begin() + 12);    // Now v becomes {1 3 10 1 3 7 8 * * * * *}    // * means undefined      // Resizing the vector so as to remove the undefined terms    v.resize(std::distance(v.begin(), ip));      // Displaying the vector after applying std::unique    for (ip = v.begin(); ip != v.end(); ++ip) {        cout << *ip << " ";    }      return 0;}Output:1 3 10 1 3 7 8
Here, in this vector, all the sub-groups having consecutive duplicate elements has been reduced to only one element. Note that it doesnot matter whether the same element is present later on as well, only duplicate elements present consecutively are handled by this function.By comparing using a pre-defined function:Syntax:template 
 ForwardIterator unique (ForwardIterator first, ForwardIterator last,
                         BinaryPredicate Pred);

Here, first and last are the same as previous case.

Pred: Binary function that accepts two elements 
in the range as argument, and returns a value convertible to bool. 
The value returned indicates whether both arguments are considered equivalent
(if true, they are equivalent and one of them is removed).
The function shall not modify any of its arguments.
This can either be a function pointer or a function object.

Return Value: It returns an iterator to the element that 
follows the last element not removed.
The range between first and this iterator includes 
all the elements in the sequence that were not
duplicates and hence not removed.// C++ program to demonstrate the use of std::unique#include <iostream>#include <algorithm>#include <string>using namespace std;  // Defining the BinaryFunctionbool Pred(char a, char b){    // Checking if both the arguments are same and equal    // to 'G' then only they are considered same    // and duplicates are removed    if (a == b && a == 'G') {        return 1;    } else {        return 0;    }}int main(){    // Declaring a string    string s = "You arre vvvisiting GGGGFGGGG";      // Using std::unique to remove the consecutive    // G in the word    auto ip = std::unique(s.begin(), s.end(), Pred);      // Displaying the corrected string    cout << string(s.begin(), ip);    return 0;}Output:You arre vvvisiting GFG
Here, we have manipulated the binary function in such a way that only if two G are passed as arguments, then only they will be considered as same, and if any other character is present consecutively, then it will remain unaffected, and will not be removed (like r in arre, v in visiting).
Comparing elements using ==:Syntax:template 
ForwardIterator unique (ForwardIterator first, ForwardIterator last);

first: Forward iterator to the first element in the container.
last: forward iterator to the last element in the container.

Return Value: It returns an iterator to the element that follows 
the last element not removed. The range between first and this iterator includes 
all the elements in the sequence that were not
duplicates and hence not removed.
// C++ program to demonstrate the use of std::unique#include <iostream>#include <vector>#include <algorithm>using namespace std;int main(){    vector<int> v = { 1, 1, 3, 3, 3, 10, 1, 3, 3, 7, 7, 8 }, i;      vector<int>::iterator ip;      // Using std::unique    ip = std::unique(v.begin(), v.begin() + 12);    // Now v becomes {1 3 10 1 3 7 8 * * * * *}    // * means undefined      // Resizing the vector so as to remove the undefined terms    v.resize(std::distance(v.begin(), ip));      // Displaying the vector after applying std::unique    for (ip = v.begin(); ip != v.end(); ++ip) {        cout << *ip << " ";    }      return 0;}Output:1 3 10 1 3 7 8
Here, in this vector, all the sub-groups having consecutive duplicate elements has been reduced to only one element. Note that it doesnot matter whether the same element is present later on as well, only duplicate elements present consecutively are handled by this function.
template 
ForwardIterator unique (ForwardIterator first, ForwardIterator last);

first: Forward iterator to the first element in the container.
last: forward iterator to the last element in the container.

Return Value: It returns an iterator to the element that follows 
the last element not removed. The range between first and this iterator includes 
all the elements in the sequence that were not
duplicates and hence not removed.

// C++ program to demonstrate the use of std::unique#include <iostream>#include <vector>#include <algorithm>using namespace std;int main(){    vector<int> v = { 1, 1, 3, 3, 3, 10, 1, 3, 3, 7, 7, 8 }, i;      vector<int>::iterator ip;      // Using std::unique    ip = std::unique(v.begin(), v.begin() + 12);    // Now v becomes {1 3 10 1 3 7 8 * * * * *}    // * means undefined      // Resizing the vector so as to remove the undefined terms    v.resize(std::distance(v.begin(), ip));      // Displaying the vector after applying std::unique    for (ip = v.begin(); ip != v.end(); ++ip) {        cout << *ip << " ";    }      return 0;}
Output:
1 3 10 1 3 7 8

Here, in this vector, all the sub-groups having consecutive duplicate elements has been reduced to only one element. Note that it doesnot matter whether the same element is present later on as well, only duplicate elements present consecutively are handled by this function.
By comparing using a pre-defined function:Syntax:template 
 ForwardIterator unique (ForwardIterator first, ForwardIterator last,
                         BinaryPredicate Pred);

Here, first and last are the same as previous case.

Pred: Binary function that accepts two elements 
in the range as argument, and returns a value convertible to bool. 
The value returned indicates whether both arguments are considered equivalent
(if true, they are equivalent and one of them is removed).
The function shall not modify any of its arguments.
This can either be a function pointer or a function object.

Return Value: It returns an iterator to the element that 
follows the last element not removed.
The range between first and this iterator includes 
all the elements in the sequence that were not
duplicates and hence not removed.// C++ program to demonstrate the use of std::unique#include <iostream>#include <algorithm>#include <string>using namespace std;  // Defining the BinaryFunctionbool Pred(char a, char b){    // Checking if both the arguments are same and equal    // to 'G' then only they are considered same    // and duplicates are removed    if (a == b && a == 'G') {        return 1;    } else {        return 0;    }}int main(){    // Declaring a string    string s = "You arre vvvisiting GGGGFGGGG";      // Using std::unique to remove the consecutive    // G in the word    auto ip = std::unique(s.begin(), s.end(), Pred);      // Displaying the corrected string    cout << string(s.begin(), ip);    return 0;}Output:You arre vvvisiting GFG
Here, we have manipulated the binary function in such a way that only if two G are passed as arguments, then only they will be considered as same, and if any other character is present consecutively, then it will remain unaffected, and will not be removed (like r in arre, v in visiting).
template 
 ForwardIterator unique (ForwardIterator first, ForwardIterator last,
                         BinaryPredicate Pred);

Here, first and last are the same as previous case.

Pred: Binary function that accepts two elements 
in the range as argument, and returns a value convertible to bool. 
The value returned indicates whether both arguments are considered equivalent
(if true, they are equivalent and one of them is removed).
The function shall not modify any of its arguments.
This can either be a function pointer or a function object.

Return Value: It returns an iterator to the element that 
follows the last element not removed.
The range between first and this iterator includes 
all the elements in the sequence that were not
duplicates and hence not removed.
// C++ program to demonstrate the use of std::unique#include <iostream>#include <algorithm>#include <string>using namespace std;  // Defining the BinaryFunctionbool Pred(char a, char b){    // Checking if both the arguments are same and equal    // to 'G' then only they are considered same    // and duplicates are removed    if (a == b && a == 'G') {        return 1;    } else {        return 0;    }}int main(){    // Declaring a string    string s = "You arre vvvisiting GGGGFGGGG";      // Using std::unique to remove the consecutive    // G in the word    auto ip = std::unique(s.begin(), s.end(), Pred);      // Displaying the corrected string    cout << string(s.begin(), ip);    return 0;}
Output:
You arre vvvisiting GFG

Here, we have manipulated the binary function in such a way that only if two G are passed as arguments, then only they will be considered as same, and if any other character is present consecutively, then it will remain unaffected, and will not be removed (like r in arre, v in visiting).
Where str::unique can be used ?
Remove all the duplicate elements from a container: Many of you must have searched for std::unique with a view that it will remove all the duplicate elements from the container, and now you might feel a bit disappointed to know that it removes only the consecutive duplicate elements. But, although, std::unique cannot do so as per its definition, but applying a bit of logic, we can make that happen. What we need to do is just sort the array before applying std::unique, such that all equal elements become consecutive, and now we have std::unique to remove all the duplicate consecutive elements.So, std::unique can also be used to remove all the duplicate elements from a container.// C++ program to demonstrate the use of std::unique#include <iostream>#include <vector>#include <algorithm>using namespace std;int main(){    vector<int> v = { 1, 2, 3, 3, 3, 10, 1, 2, 3, 7, 7, 8 };      vector<int>::iterator ip;      // Sorting the array    std::sort(v.begin(), v.end());    // Now v becomes 1 1 2 2 3 3 3 3 7 7 8 10      // Using std::unique    ip = std::unique(v.begin(), v.begin() + 12);    // Now v becomes {1 2 3 7 8 10 * * * * * *}    // * means undefined      // Resizing the vector so as to remove the undefined terms    v.resize(std::distance(v.begin(), ip));      // Displaying the vector after applying std::unique    for (ip = v.begin(); ip != v.end(); ++ip) {        cout << *ip << " ";    }      return 0;}Output:1 2 3 7 8 10
Explanation: Firstly, we sorted the array such that all the equal duplicate elements become consecutive and now applying std::unique to it such that the duplicacy is removed, and in this way we remove all the duplicate elements from a container, whether consecutive or not.Count unique elements : It can also be used if we want to count the total no. of unique elements in a container.// C++ program to demonstrate the use of std::unique#include <iostream>#include <iterator>#include <vector>#include <algorithm>using namespace std;int main(){    vector<int> v = { 1, 1, 3, 3, 3, 10, 1, 3, 3, 7, 7, 8 };      vector<int>::iterator ip;      int count;    sort(v.begin(), v.end());      // Using std::unique and std::distance to count    // unique elements in a container    count = std::distance(v.begin(),                          std::unique(v.begin(), v.begin() + 12));      // Displaying the value of count    cout << "Total no. of unique elements = " << count;      return 0;}Output:Total no. of unique elements = 5
Explanation: As we know that std::unique returns an iterator to what should be the new end of the container after removing duplicate elements, so just counting the total no. of elements from beginning till this new end with the help of std::distance, should give us the total no. of unique elements in the container.
Remove all the duplicate elements from a container: Many of you must have searched for std::unique with a view that it will remove all the duplicate elements from the container, and now you might feel a bit disappointed to know that it removes only the consecutive duplicate elements. But, although, std::unique cannot do so as per its definition, but applying a bit of logic, we can make that happen. What we need to do is just sort the array before applying std::unique, such that all equal elements become consecutive, and now we have std::unique to remove all the duplicate consecutive elements.So, std::unique can also be used to remove all the duplicate elements from a container.// C++ program to demonstrate the use of std::unique#include <iostream>#include <vector>#include <algorithm>using namespace std;int main(){    vector<int> v = { 1, 2, 3, 3, 3, 10, 1, 2, 3, 7, 7, 8 };      vector<int>::iterator ip;      // Sorting the array    std::sort(v.begin(), v.end());    // Now v becomes 1 1 2 2 3 3 3 3 7 7 8 10      // Using std::unique    ip = std::unique(v.begin(), v.begin() + 12);    // Now v becomes {1 2 3 7 8 10 * * * * * *}    // * means undefined      // Resizing the vector so as to remove the undefined terms    v.resize(std::distance(v.begin(), ip));      // Displaying the vector after applying std::unique    for (ip = v.begin(); ip != v.end(); ++ip) {        cout << *ip << " ";    }      return 0;}Output:1 2 3 7 8 10
Explanation: Firstly, we sorted the array such that all the equal duplicate elements become consecutive and now applying std::unique to it such that the duplicacy is removed, and in this way we remove all the duplicate elements from a container, whether consecutive or not.
So, std::unique can also be used to remove all the duplicate elements from a container.
// C++ program to demonstrate the use of std::unique#include <iostream>#include <vector>#include <algorithm>using namespace std;int main(){    vector<int> v = { 1, 2, 3, 3, 3, 10, 1, 2, 3, 7, 7, 8 };      vector<int>::iterator ip;      // Sorting the array    std::sort(v.begin(), v.end());    // Now v becomes 1 1 2 2 3 3 3 3 7 7 8 10      // Using std::unique    ip = std::unique(v.begin(), v.begin() + 12);    // Now v becomes {1 2 3 7 8 10 * * * * * *}    // * means undefined      // Resizing the vector so as to remove the undefined terms    v.resize(std::distance(v.begin(), ip));      // Displaying the vector after applying std::unique    for (ip = v.begin(); ip != v.end(); ++ip) {        cout << *ip << " ";    }      return 0;}
Output:
1 2 3 7 8 10

Explanation: Firstly, we sorted the array such that all the equal duplicate elements become consecutive and now applying std::unique to it such that the duplicacy is removed, and in this way we remove all the duplicate elements from a container, whether consecutive or not.
Count unique elements : It can also be used if we want to count the total no. of unique elements in a container.// C++ program to demonstrate the use of std::unique#include <iostream>#include <iterator>#include <vector>#include <algorithm>using namespace std;int main(){    vector<int> v = { 1, 1, 3, 3, 3, 10, 1, 3, 3, 7, 7, 8 };      vector<int>::iterator ip;      int count;    sort(v.begin(), v.end());      // Using std::unique and std::distance to count    // unique elements in a container    count = std::distance(v.begin(),                          std::unique(v.begin(), v.begin() + 12));      // Displaying the value of count    cout << "Total no. of unique elements = " << count;      return 0;}Output:Total no. of unique elements = 5
Explanation: As we know that std::unique returns an iterator to what should be the new end of the container after removing duplicate elements, so just counting the total no. of elements from beginning till this new end with the help of std::distance, should give us the total no. of unique elements in the container.
// C++ program to demonstrate the use of std::unique#include <iostream>#include <iterator>#include <vector>#include <algorithm>using namespace std;int main(){    vector<int> v = { 1, 1, 3, 3, 3, 10, 1, 3, 3, 7, 7, 8 };      vector<int>::iterator ip;      int count;    sort(v.begin(), v.end());      // Using std::unique and std::distance to count    // unique elements in a container    count = std::distance(v.begin(),                          std::unique(v.begin(), v.begin() + 12));      // Displaying the value of count    cout << "Total no. of unique elements = " << count;      return 0;}
Output:
Total no. of unique elements = 5

Explanation: As we know that std::unique returns an iterator to what should be the new end of the container after removing duplicate elements, so just counting the total no. of elements from beginning till this new end with the help of std::distance, should give us the total no. of unique elements in the container.
This article is contributed by Mrigendra Singh. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
cpp-algorithm-library
STL
C++
Misc
Misc
Misc
STL
CPP
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Bitwise Operators in C/C++
vector erase() and clear() in C++
Inheritance in C++
Priority Queue in C++ Standard Template Library (STL)
The C++ Standard Template Library (STL)
Overview of Data Structures | Set 1 (Linear Data Structures)
vector::push_back() and vector::pop_back() in C++ STL
Top 10 algorithms in Interview Questions
How to write Regular Expressions?
Program for nth Catalan Number