Namespaces
Variants

std::ranges:: partition

From cppreference.net
Algorithm library
Constrained algorithms and algorithms on ranges (C++20)
Constrained algorithms, e.g. ranges::copy , ranges::sort , ...
Execution policies (C++17)
Non-modifying sequence operations
Batch operations
(C++17)
Search operations
Modifying sequence operations
Copy operations
(C++11)
(C++11)
Swap operations
Transformation operations
Generation operations
Removing operations
Order-changing operations
(until C++17) (C++11)
(C++20) (C++20)
Sampling operations
(C++17)

Sorting and related operations
Partitioning operations
Sorting operations
Binary search operations
(on partitioned ranges)
Set operations (on sorted ranges)
Merge operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Lexicographical comparison operations
Permutation operations
C library
Numeric operations
Operations on uninitialized memory
Constrained algorithms
All names in this menu belong to namespace std::ranges
Non-modifying sequence operations
Modifying sequence operations
Partitioning operations
Sorting operations
Binary search operations (on sorted ranges)
Set operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Permutation operations
Fold operations
Operations on uninitialized storage
Return types
Défini dans l'en-tête <algorithm>
Signature d'appel
template < std:: permutable I, std:: sentinel_for < I > S, class Proj = std:: identity ,

std:: indirect_unary_predicate < std :: projected < I, Proj >> Pred >
constexpr ranges:: subrange < I >

partition ( I first, S last, Pred pred, Proj proj = { } ) ;
(1) (depuis C++20)
template < ranges:: forward_range R, class Proj = std:: identity ,

std:: indirect_unary_predicate <
std :: projected < ranges:: iterator_t < R > , Proj >> Pred >
requires std:: permutable < ranges:: iterator_t < R >>
constexpr ranges:: borrowed_subrange_t < R >

partition ( R && r, Pred pred, Proj proj = { } ) ;
(2) (depuis C++20)
1) Réorganise les éléments dans la plage [ first , last ) de telle manière que la projection proj de tous les éléments pour lesquels le prédicat pred retourne true précède la projection proj des éléments pour lesquels le prédicat pred retourne false . L'ordre relatif des éléments n'est pas préservé.
2) Identique à (1) , mais utilise r comme plage source, comme si on utilisait ranges:: begin ( r ) comme first et ranges:: end ( r ) comme last .

Les entités de type fonction décrites sur cette page sont des algorithm function objects (informellement appelées niebloids ), c'est-à-dire :

Table des matières

Paramètres

first, last - la paire itérateur-sentinelle définissant la plage des éléments à réorganiser
r - la plage d'éléments à réorganiser
pred - prédicat à appliquer aux éléments projetés
proj - projection à appliquer aux éléments

Valeur de retour

Un sous-intervalle commençant par un itérateur vers le premier élément du deuxième groupe et se terminant par un itérateur égal à last . (2) renvoie std::ranges::dangling si r est une rvalue d'un type non- borrowed_range .

Complexité

Étant donné N = ranges:: distance ( first, last ) , exactement N applications du prédicat et de la projection. Au maximum N / 2 échanges si I modélise ranges::bidirectional_iterator , et au maximum N échanges sinon.

Implémentation possible

struct partition_fn
{
    template<std::permutable I, std::sentinel_for<I> S, class Proj = std::identity,
             std::indirect_unary_predicate<std::projected<I, Proj>> Pred>
    constexpr ranges::subrange<I>
        operator()(I first, S last, Pred pred, Proj proj = {}) const
    {
        first = ranges::find_if_not(first, last, std::ref(pred), std::ref(proj));
        if (first == last)
            return {first, first};
        for (auto i = ranges::next(first); i != last; ++i)
        {
            if (std::invoke(pred, std::invoke(proj, *i)))
            {
                ranges::iter_swap(i, first);
                ++first;
            }
        }
        return {std::move(first), std::move(last)};
    }
    template<ranges::forward_range R, class Proj = std::identity,
             std::indirect_unary_predicate<
                 std::projected<ranges::iterator_t<R>, Proj>> Pred>
    requires std::permutable<ranges::iterator_t<R>>
    constexpr ranges::borrowed_subrange_t<R>
        operator()(R&& r, Pred pred, Proj proj = {}) const
    {
        return (*this)(ranges::begin(r), ranges::end(r),
                       std::ref(pred), std::ref(proj));
    }
};
inline constexpr partition_fn partition;

Exemple

#include <algorithm>
#include <forward_list>
#include <functional>
#include <iostream>
#include <iterator>
#include <ranges>
#include <vector>
namespace ranges = std::ranges;
template<class I, std::sentinel_for<I> S, class Cmp = ranges::less>
requires std::sortable<I, Cmp>
void quicksort(I first, S last, Cmp cmp = Cmp {})
{
    using reference = std::iter_reference_t<I>;
    if (first == last)
        return;
    auto size = ranges::distance(first, last);
    auto pivot = ranges::next(first, size - 1);
    ranges::iter_swap(pivot, ranges::next(first, size / 2));
    auto tail = ranges::partition(first, pivot, [=](reference em)
    {
        return std::invoke(cmp, em, *pivot); // em < pivot
    });
    ranges::iter_swap(pivot, tail.begin());
    quicksort(first, tail.begin(), std::ref(cmp));
    quicksort(ranges::next(tail.begin()), last, std::ref(cmp));
}
int main()
{
    std::ostream_iterator<int> cout {std::cout, " "};
    std::vector<int> v {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    std::cout << "Vecteur original :  \t";
    ranges::copy(v, cout);
    auto tail = ranges::partition(v, [](int i) { return i % 2 == 0; });
    std::cout << "\nVecteur partitionné : \t";
    ranges::copy(ranges::begin(v), ranges::begin(tail), cout);
    std::cout << "│ ";
    ranges::copy(tail, cout);
    std::forward_list<int> fl {1, 30, -4, 3, 5, -4, 1, 6, -8, 2, -5, 64, 1, 92};
    std::cout << "\nListe non triée : \t\t";
    ranges::copy(fl, cout);
    quicksort(ranges::begin(fl), ranges::end(fl), ranges::greater {});
    std::cout << "\nListe triée par tri rapide : \t";
    ranges::copy(fl, cout);
    std::cout << '\n';
}

Sortie possible :

Vecteur original :        0 1 2 3 4 5 6 7 8 9
Vecteur partitionné :     0 8 2 6 4 │ 5 3 7 1 9
Liste non triée :         1 30 -4 3 5 -4 1 6 -8 2 -5 64 1 92
Liste triée par quicksort :      92 64 30 6 5 3 2 1 1 1 -4 -4 -5 -8

Voir aussi

copie une plage en divisant les éléments en deux groupes
(objet fonction algorithme)
détermine si la plage est partitionnée par le prédicat donné
(objet fonction algorithme)
divise les éléments en deux groupes en préservant leur ordre relatif
(objet fonction algorithme)
divise une plage d'éléments en deux groupes
(modèle de fonction)