C++ Algorithm unique_copy method is employed to duplicate a sequence where every repeated consecutive element is transformed into a distinct element. This operation does not modify the initial range but instead duplicates the outcome into a separate container. The initial version compares elements using operator==, while the alternative version utilizes the specified binary predicate pred.
Syntax
equality (1) template <class InputIterator, class OutputIterator>
OutputIterator unique_copy (InputIterator first, InputIterator last,
OutputIterator result);
predicate (2) template <class InputIterator, class OutputIterator, class BinaryPredicate>
OutputIterator unique_copy (InputIterator first, InputIterator last,
OutputIterator result, BinaryPredicate pred);
Parameter
A forward iterator indicating the location of the initial element within the range intended for duplication.
last: A forward iterator indicating the location immediately following the last element within the specified range intended for duplication.
A custom predicate function object created by the user to specify the criteria for considering two elements in a range as equivalent. This binary predicate takes two arguments and evaluates to true if the condition is met, or false if it is not met.
An output iterator indicates the location of the initial element within the duplicated-free copied range.
Return value
An iterator pointing to the updated end of the duplicated range [first, last) that excludes consecutive identical elements.
Complexity
The time complexity is linear within the specified range [first, last): it compares each pair of adjacent elements and executes assignment operations on certain elements.
Data races
The elements within the range [first, last) are accessed, while the elements between the result and the value returned are altered.
Exception safety
This function will raise an exception if any errors occur during the evaluation of the predicate, comparisons between elements, assignments of elements, or operations on iterators.
Please be aware that using incorrect parameters can lead to unpredictable behavior.
Example 1
Let's explore a straightforward example to showcase the application of unique_copy function, where elements are compared using the operator==.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
vector<int> v = { 100, 100, 300, 300, 300, 500, 100,
300, 300, 600, 600, 700 };
// vector to store the copied value
vector<int> v1(10);
vector<int>::iterator ip;
// Using unique_copy
ip = unique_copy(v.begin(), v.begin() + 12, v1.begin());
// Resizing vector v1
v1.resize(distance(v1.begin(), ip));
cout << "Before: ";
for (ip = v.begin(); ip != v.end(); ++ip)
{
cout << *ip << " ";
}
// Displaying vector after applying unique_copy
cout << "\n\nAfter: ";
for (ip = v1.begin(); ip != v1.end(); ++ip)
{
cout << *ip << " ";
}
return 0;
}
Output:
Before: 100 100 300 300 300 500 100 300 300 600 600 700
After: 100 300 500 100 300 600 700
All the consecutive duplicate elements within the vector v have been condensed to a single element and then replicated into a new vector named v1.
Example 2
Let's explore another straightforward example to demonstrate the application of unique_copy where elements will be compared using a predefined function:
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
// declaring a BinaryFunction
bool Pred(char a, char b)
{
// It checks if the 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 vvvogie bbogie", s1;
// Using std::unique_copy to remove the consecutive
// v in the word and copy it to s1
auto ip = unique_copy(s.begin(), s.end(), back_inserter(s1), Pred);
cout << "Before: " << s;
// Displaying the corrected string
cout << "\nAfter: " << s1;
return 0;
}
Output:
Before: You arre vvvisiting vvvogie bbogie
After: You arre visiting vogie bbogie
Example 3
Let's examine another straightforward example to verify if the container includes duplicate elements or not:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
vector<int> v = { 1, 4, 3, 5, 2, 7, 6 };
vector<int>::iterator ip;
// Sorting the array to make duplicate elements
// consecutive
sort(v.begin(), v.end());
// Now v becomes 1 2 3 4 5 6 7
// Declaring a container to store the unique elements
vector<int> v1(7);
// Using unique_copy
ip = unique_copy(v.begin(), v.end(), v1.begin());
// Now v1 becomes {1 2 3 4 5 6 7 }
if (v == v1)
{
cout << "v1 contains only unique elements";
}
else
{
cout << "v1 contains duplicate elements";
}
return 0;
}
Output:
v1 contains only unique elements
First, the process involves eliminating redundant elements from the vector v and saving the unique elements in a new vector called v1. Subsequently, a comparison is made between v1 and v to ensure that they are identical. This comparison confirms that the original vector v exclusively consists of distinct elements with no duplicates.
Example 4
Let's explore another basic illustration for eliminating all the spaces within the provided statement:
#include <string>
#include <iostream>
#include <algorithm>
#include <iterator>
using namespace std;
int main()
{
string s1 = "The string with many spaces!";
cout << "before: " << s1 << '\n';
string s2;
unique_copy(s1.begin(), s1.end(), std::back_inserter(s2),
[](char c1, char c2){ return c1 == ' ' && c2 == ' '; });
cout << "after: " << s2 << '\n';
}
Output:
before: The string with many spaces!
after: The string with many spaces!