std::partition_copy: Efektivní rozdělení dat v C++
Při práci s daty v C++ se často setkáváme s potřebou rozdělit kolekci na dvě části podle určité podmínky. Standardní knihovna C++ nabízí elegantní řešení tohoto problému pomocí algoritmu std::partition_copy. Tento algoritmus je součástí hlavičkového souboru <algorithm> a poskytuje efektivní způsob, jak rozdělit prvky vstupní kolekce do dvou samostatných výstupních kolekcí.
Co je std::partition_copy?
std::partition_copy je algoritmus, který iteruje přes prvky vstupní kolekce a kopíruje je do dvou různých výstupních kolekcí na základě splnění zadané podmínky (predikátu). Prvky, které splňují podmínku, jsou zkopírovány do jedné kolekce, zatímco ostatní prvky jsou zkopírovány do druhé.
Syntaxe
std::partition_copy(input_begin, input_end, output_true, output_false, predicate);
input_beginainput_end: Iterátory určující rozsah vstupní kolekce.output_true: Začátek výstupní kolekce pro prvky splňující podmínku.output_false: Začátek výstupní kolekce pro prvky, které podmínku nesplňují.predicate: Funkce nebo lambda výrazu, který definuje podmínku.
Příklad použití
Podívejme se na jednoduchý příklad, jak std::partition_copy funguje:
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
std::vector<int> even;
std::vector<int> odd;
// Rezervace místa pro výstupní kolekce
even.resize(numbers.size());
odd.resize(numbers.size());
// Rozdělení čísel na sudá a lichá
auto it = std::partition_copy(
numbers.begin(), numbers.end(),
even.begin(), odd.begin(),
[](int n) { return n % 2 == 0; }
);
// Úprava velikosti výstupních kolekcí
even.resize(std::distance(even.begin(), it.first));
odd.resize(std::distance(odd.begin(), it.second));
// Výstup
std::cout << "Sudá čísla: ";
for (int n : even) std::cout << n << " ";
std::cout << "\nLichá čísla: ";
for (int n : odd) std::cout << n << " ";
return 0;
}
Vysvětlení kódu
- Vstupní kolekce: Vektor
numbersobsahuje čísla od 1 do 10. - Výstupní kolekce: Dva vektory
evenaoddjsou inicializovány s dostatečnou kapacitou. - Predikát: Lambda funkce kontroluje, zda je číslo sudé.
- Výstupní iterátory: Funkce
std::partition_copyvrací dvojici iterátorů, které označují konce naplněných výstupních kolekcí. - Úprava velikosti: Po rozdělení je velikost výstupních kolekcí upravena pomocí
std::distance.
Výhody std::partition_copy
- Bezpečnost dat: Na rozdíl od
std::partitionnemění původní kolekci. - Flexibilita: Umožňuje snadné oddělení dat do dvou různých kolekcí.
- Efektivita: Algoritmus má lineární časovou složitost $O(n)$.
Závěr
std::partition_copy je užitečný nástroj pro rozdělení dat na základě podmínky, aniž by došlo k modifikaci původní kolekce. Je ideální pro situace, kdy potřebujete zachovat původní data a zároveň je rozdělit do dvou samostatných skupin. Díky jednoduché syntaxi a podpoře lambda funkcí je tento algoritmus snadno použitelný i v moderním C++ kódu.