std::unique_copy in C++

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.

But, what if we don’t want to alter with the original range and just want the result of std::unique to be copied into another container, for this we have another function defined in , i.e., std::unique_copy(). In this, only the first element from every consecutive group of equivalent elements in the range [first, last) is copied.

It can be used in two ways as shown below:

  1. Comparing elements using ==:
    Syntax:

    template 
      OutputIterator unique_copy (InputIterator first, InputIterator last,
                                  OutputIterator result);
    
    first: Forward iterator to the first element in the container.
    last: Forward iterator to the last element in the container.
    result: Output iterator to the initial position 
    of the container where the resulting range of values is stored. 
    The value being pointed should be compatible with the value being assigned.
    
    Return Value: An iterator pointing to the end 
    of the copied range, which contains no consecutive duplicates.
    
    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    // C++ program to demonstrate 
    // the use of std::unique_copy
    #include <iostream>
    #include <vector>
    #include <algorithm>
    using namespace std;
    int main()
    {
        vector<int> v = { 10, 10, 30, 30, 30, 100, 10,
                          300, 300, 70, 70, 80 };
      
        // Declaring a vector to store the copied value
        vector<int> v1(10);
      
        vector<int>::iterator ip;
      
        // Using std::unique_copy
        ip = std::unique_copy(v.begin(), v.begin() + 12, v1.begin());
        // Now v1 contains {10 30 100 10 30 70 80 0 0 0}
      
        // Resizing vector v1
        v1.resize(std::distance(v1.begin(), ip));
      
        cout << "Before: ";
        for (ip = v.begin(); ip != v.end(); ++ip) 
        {
            cout << *ip << " ";
        }
      
        // Displaying the vector after applying std::unique_copy
        cout << "\nAfter: ";
        for (ip = v1.begin(); ip != v1.end(); ++ip) 
        {
            cout << *ip << " ";
        }
      
        return 0;
    }

    chevron_right

    
    

    Output:

    Before: 10 10 30 30 30 100 10 300 300 70 70 80
    After: 10 30 100 10 30 70 80 
    

    Here, in this vector, all the sub-groups having consecutive duplicate elements have been reduced to only one element, and have been copied to vector v1.

  2. By comparing using a pre-defined function:
    Syntax:

    template 
      OutputIterator unique_copy (InputIterator first, InputIterator last,
                                  OutputIterator result, BinaryPredicate pred);
    
    Here, first, last and result 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 pointing to the 
    end of the copied range, which contains no consecutive duplicates.
    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    // C++ program to demonstrate the 
    // use of std::unique_copy
    #include <iostream>
    #include <algorithm>
    #include <string>
    using namespace std;
      
    // Defining the BinaryFunction
    bool Pred(char a, char b)
    {
        // Checking if both the arguments are same and equal
        // to 'v' then only they are considered same
        // and duplicates are removed
        if (a == b && a == 'v'
        {
            return 1;
        
        else 
        {
            return 0;
        }
    }
    int main()
    {
        // Declaring a string
        string s = "You arre vvvisiting GFG", s1;
      
        // Using std::unique_copy to remove the consecutive
        // v in the word and copy it to s1
        auto ip = std::unique_copy(s.begin(), s.end(), back_inserter(s1), Pred);
      
        cout << "Before: " << s;
      
        // Displaying the corrected string
        cout << "\nAfter: " << s1;
        return 0;
    }

    chevron_right

    
    

    Output:

    Before: You arre vvvisiting GFG
    After: You arre visiting GFG
    

Where can it be used ?

  1. std::unique_copy can be used to remove all the duplicate elements (whether consecutive or not) and store the resultant in another container, without affecting the previous container.
    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    // C++ program to demonstrate the use of std::unique_copy
    #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 to make duplicate elements
        // consecutive
        std::sort(v.begin(), v.end());
        // Now v becomes 1 1 2 2 3 3 3 3 7 7 8 10
      
        // Declaring a container to store the unique elements
        vector<int> v1(6);
      
        // Using std::unique_copy
        ip = std::unique_copy(v.begin(), v.begin() + 12, v1.begin());
        // Now v1 becomes {1 2 3 7 8 10}
      
        // Displaying the vector v and v1 after applying std::unique
        cout << "v = ";
      
        for (ip = v.begin(); ip != v.end(); ++ip) 
        {
            cout << *ip << " ";
        }
      
        cout << "\nv1 = ";
        for (ip = v1.begin(); ip != v1.end(); ++ip) 
        {
            cout << *ip << " ";
        }
      
        return 0;
    }

    chevron_right

    
    

    Output:

    v = 1 1 2 2 3 3 3 3 7 7 8 10
    v1 = 1 2 3 7 8 10
    

    Explanation: Here, we have firstly sorted the vector to make duplicate elements consecutive and then applied std::unique_copy to remove duplicate elements and store the unique elements in another container.

  2. We can also use std::unique_copy to find whether a container contains only unique elements or not. This is just an extension of the above concept of storing the unique elements in another container. After this, we can just compare the two containers to check whether they are equal or not.
    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    // C++ program to demonstrate the use of std::unique_copy
    #include <iostream>
    #include <vector>
    #include <algorithm>
    using namespace std;
    int main()
    {
        vector<int> v = { 1, 20, 3, 10, 2, 7, 8 };
      
        vector<int>::iterator ip;
      
        // Sorting the array to make duplicate elements
        // consecutive
        std::sort(v.begin(), v.end());
        // Now v becomes 1 2 3 7 8 10 20
      
        // Declaring a container to store the unique elements
        vector<int> v1(7);
      
        // Using std::unique_copy
        ip = std::unique_copy(v.begin(), v.end(), v1.begin());
        // Now v1 becomes {1 2 3 7 8 10 20}
      
        if (v == v1) 
        {
            cout << "v1 contains only unique elements";
        
        else 
        {
            cout << "v1 contains duplicate elements";
        }
        return 0;
    }

    chevron_right

    
    

    Output:

    v1 contains only unique elements
    

    Explanation: Firstly, we removed the duplicate elements and stored the resultant in another container and then compared the resultant container with the previous container, if both are same, this means that the previous container consisted of only unique elements, and there is no duplicate element.

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.



My Personal Notes arrow_drop_up


Article Tags :
Practice Tags :


Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.