std::partition în C++

Împarte elementele în două grupuri: întâi cele care îndeplinesc condiția, apoi celelalte.

Sintaxă
ForwardIt partition(ForwardIt first, ForwardIt last, UnaryPred conditie);
BidirIt stable_partition(BidirIt first, BidirIt last, UnaryPred conditie);

Ce face std::partition

std::partition rearanjează intervalul astfel încât toate elementele pentru care condiția este true ajung înaintea celor pentru care este false. Returnează iteratorul către primul element din al doilea grup. Ordinea din fiecare grup nu este păstrată.

std::stable_partition face același lucru, dar păstrează ordinea relativă din fiecare grup, cu prețul unei memorii suplimentare.

Parametri

Parametru Descriere
first, last Intervalul.
conditie Funcția care decide grupul fiecărui element.

Ce returnează

Iterator către începutul celui de-al doilea grup.

Exemple

Exemplul 1: Pare înaintea impare (stabil)

Cu stable_partition, numerele pare rămân în ordinea 8, 2, 6, iar cele impare în ordinea 3, 7, 5.

#include <algorithm>
#include <print>
#include <vector>

int main() {
    std::vector<int> v{3, 8, 7, 2, 5, 6};

    auto granita = std::stable_partition(v.begin(), v.end(), [](int x) { return x % 2 == 0; });

    std::println("Pare: {}", std::vector<int>(v.begin(), granita));
    std::println("Impare: {}", std::vector<int>(granita, v.end()));
}

Rezultat

Pare: [8, 2, 6]
Impare: [3, 7, 5]

Exemplul 2: Câți elevi au trecut (partition)

La std::partition ordinea din grupuri poate diferi, dar numărul elementelor din fiecare grup este sigur.

#include <algorithm>
#include <print>
#include <vector>

int main() {
    std::vector<double> note{9.5, 4.0, 7.25, 3.5, 10.0, 6.0};

    auto granita = std::partition(note.begin(), note.end(), [](double n) { return n >= 5; });
    std::println("Promovați: {}, corigenți: {}", granita - note.begin(), note.end() - granita);
}

Rezultat

Promovați: 4, corigenți: 2

Greșeli frecvente

  • Te bazezi pe ordinea elementelor după std::partition. Dacă ordinea contează, folosește std::stable_partition.

Comenzi înrudite

  • std::stable_sort: Sortează un interval păstrând ordinea inițială a elementelor considerate egale.
  • std::copy_if: Copiază doar elementele care îndeplinesc o condiție, păstrând ordinea lor.
  • std::remove_if: Elimină logic elementele care îndeplinesc o condiție; folosit cu erase sau înlocuit de std::erase_if (C++20).
  • std::nth_element: Pune pe poziția n elementul care ar fi acolo după sortare; util pentru mediană sau al k-lea cel mai mic.