The C++ algorithm partition_copy method is employed to duplicate elements that meet a certain condition to one target and those that do not to another. These elements should be within a defined range.
Syntax
template <class InputIterator, class OutputIterator1,
class OutputIterator2, class UnaryPredicate pred>
pair<OutputIterator1,OutputIterator2>
partition_copy (InputIterator first, InputIterator last,
OutputIterator1 result_true, OutputIterator2 result_false,
UnaryPredicate pred);
Parameter
An input iterator that points to the initial element within the range to be examined for a specific condition.
last : An input iterator pointing to the element following the final element in the range.
pred : A custom unary predicate function created by the user to specify the condition for testing.
An output iterator is employed to duplicate elements that meet the condition specified by pred.
result_false: An output iterator is employed to duplicate elements that do not meet the condition specified by the predicate function.
Return value
This function provides a pair of iterators pointing to the end of the generated sequences, indicated by resulttrue and resultfalse.
Complexity
The time complexity is linear within the specified range [first, last) as long as there is sufficient memory available. This involves applying the pred function to every element and carrying out an assignment operation for each individual element.
Data races
The elements within the range [first, last) are iterated through, ensuring each element is accessed only once.
Exceptions
This function raises an exception if any of the predicate, an element's assignment, or an operation on the iterator results in an exception.
Note: The invalid parameters cause an undefined behavior.
Example 1
Let's explore a basic example to showcase the functionality of the partition_copy method:
#include <iostream> // std::cout
#include <algorithm> // std::partition_copy, std::count_if
#include <vector> // std::vector
using namespace std;
bool IsOdd (int i) { return (i%2)==1; }
int main () {
vector<int> foo {1,2,3,4,5,6,7,8,9};
vector<int> odd, even;
// resize vectors to proper size:
unsigned n = count_if (foo.begin(), foo.end(), IsOdd);
odd.resize(n); even.resize(foo.size()-n);
// partition:
partition_copy (foo.begin(), foo.end(), odd.begin(), even.begin(), IsOdd);
// print contents:
cout << "odd is: "; for (int& x:odd) cout << ' ' << x; cout << '\n';
cout << "even is: "; for (int& x:even) cout << ' ' << x; cout << '\n';
return 0;
}
Output:
odd is: 1 3 5 7 9
even is: 2 4 6 8
Example 2
Let's see another simple example:
#include <iostream>
#include <algorithm>
#include <utility>
using namespace std;
int main()
{
int arr [10] = {1,2,3,4,5,6,7,8,9,10};
int true_arr [5] = {0};
int false_arr [5] = {0};
partition_copy(begin(arr), end(arr), begin(true_arr),begin(false_arr),
[] (int i) {return i > 5;});
cout << "true_arr: ";
for (int x : true_arr) {
cout << x << ' ';
}
cout << '\n';
cout << "false_arr: ";
for (int x : false_arr) {
cout << x << ' ';
}
cout << '\n';
return 0;
}
Output:
true_arr: 6 7 8 9 10
false_arr: 1 2 3 4 5
Example 3
Let's see another simple example:
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <string>
using namespace std;
void print(const string& name, const vector<int>& v)
{
cout << name << " : ";
for_each(v.begin(), v.end(), [](int x) {
cout << x << ",";
});
cout << endl;
}
bool is_even(int x) { return x % 2 == 0; }
int main()
{
vector<int> v = {1, 2, 3, 4, 5};
vector<int> evens;
vector<int> odds;
partition_copy(v.begin(), v.end(),
back_inserter(evens),
back_inserter(odds),
is_even);
print("v", v);
print("evens", evens);
print("odds ", odds);
return 0;
}
Output:
v : 1,2,3,4,5,
evens : 2,4,
odds : 1,3,5,
Example 4
Let's see another simple example:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
bool is_even(int num)
{
return (num % 2 == 0);
}
void print_vector(const vector<int> & VecRef)
{
cout << endl;
cout << "Contents of the vector is : " << endl;
for (auto it = VecRef.begin(); it != VecRef.end(); ++it) {
cout << "[" << it - VecRef.begin() << "] : " << *it << endl;
}
}
int main()
{
vector<int> NumbersVec;
for (int cnt = 1; cnt < 10; ++cnt)
NumbersVec.push_back(cnt);
vector<int> EvenVec, OddVec;
unsigned countEven = count_if(NumbersVec.begin(), NumbersVec.end(), is_even);
cout << "Evens : " << countEven << endl; //Prints 4
cout << "Odds : " << NumbersVec.size() - countEven << endl; //Prints 5
EvenVec.resize(countEven);
OddVec.resize(NumbersVec.size() - countEven);
partition_copy(NumbersVec.begin(), NumbersVec.end(), EvenVec.begin(), OddVec.begin(), is_even);
// partition_copy(NumbersVec.begin(), NumbersVec.end(), back_inserter(EvenVec), back_inserter(OddVec), is_even); This works...
print_vector(EvenVec);
print_vector(OddVec); // <== this one crashes
return 0;
}
Output:
Evens : 4
Odds : 5
Contents of the vector is :
[0] : 2
[1] : 4
[2] : 6
[3] : 8
Contents of the vector is :
[0] : 1
[1] : 3
[2] : 5
[3] : 7
[4] : 9