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_begin a input_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

  1. Vstupní kolekce: Vektor numbers obsahuje čísla od 1 do 10.
  2. Výstupní kolekce: Dva vektory even a odd jsou inicializovány s dostatečnou kapacitou.
  3. Predikát: Lambda funkce kontroluje, zda je číslo sudé.
  4. Výstupní iterátory: Funkce std::partition_copy vrací dvojici iterátorů, které označují konce naplněných výstupních kolekcí.
  5. Ú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::partition nemě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.

ai (1) architekt (1) Bash (2) bitwig (2) bitwig6 (1) c++ (54) cheatsheet (1) clang-format (1) class (1) cmake (3) cmake-format (1) conan (2) constexpr if (1) cz (2) daw (2) decltype(x) (1) desktop (2) duševní zdraví (1) email (1) emoce (4) enum (1) enum class (1) functor (1) git (1) gnome (4) gnome-extension (1) helloworld (2) hranice (1) js (1) keyboard (2) linux (6) llm (1) lvalue (1) metodika řízení (2) midi (2) modern c++ (48) motivace (1) music (6) music production (1) native instruments (1) nodiscard (1) noexcept (1) operator (1) osobnost (1) osobní hranice (1) override (1) package manager (1) Perfect Forwarding (1) plugin (1) poděkování (1) polymorfism (1) prospěch (1) psyché (2) python (2) rspamd (1) rvalue (1) růst (2) scale (2) self-stress (1) sociální sítě (1) software (1) spam (1) std (28) std::accumulate (1) std::async (2) std::divides (1) std::filesystem::path (2) std::forward (1) std::future (3) std::istream_iterator (1) std::latch (1) std::lerp (1) std::minus (1) std::modulus (1) std::multiplies (1) std::negate (1) std::ostream_iterator (1) std::packaged_task (1) std::partition (1) std::partition_copy (1) std::plus (1) std::promise (2) std::shiftleft (1) std::shuffle (1) std::transform (1) std::tuple (1) std::variant (1) std::views::transform (1) std::visit (1) strach (1) strategie (1) synthesizer (1) toxic (2) toxicita (1) toxík (1) using (2) vztah k sobě (1) vztahy (3) vývoj (1) zdraví (2)