Namespaces
Variants

std::partition

De fr.cppreference.net
 
 
Bibliothèque d'algorithmes
Algorithmes contraints et algorithmes sur plages (C++20)
Algorithmes contraints, p. ex. ranges::copy, ranges::sort, ...
Opérations de séquence non modificatrices    
Opérations par lot
(C++17)
Opérations de recherche
Opérations de séquence modificatrices
Opérations de copie
(C++11)
(C++11)
Opérations d'échange
Opérations de transformation
Opérations de génération
Opérations de suppression
Opérations de changement d'ordre
(jusqu'à C++17)(C++11)
(C++20)(C++20)
Opérations d'échantillonnage
(C++17)

Opérations de tri et connexes
Opérations de partitionnement
(C++11)    

Opérations de tri
Opérations de recherche binaire
(sur plages partitionnées)
Opérations ensemblistes (sur plages triées)
Opérations de fusion (sur plages triées)
Opérations de tas
Opérations de minimum/maximum
(C++11)
(C++17)
Opérations de comparaison lexicographique
Opérations de permutation


 
Défini dans l'en-tête <algorithm>
template< class ForwardIt, class UnaryPred >
ForwardIt partition( ForwardIt first, ForwardIt last, UnaryPred p );
(1) (constexpr depuis C++20)
template< class ExecutionPolicy, class ForwardIt, class UnaryPred >
ForwardIt partition( ExecutionPolicy&& policy, 
                     ForwardIt first, ForwardIt last, UnaryPred p );
(2) (depuis C++17)
1) Réordonne les éléments dans la plage [firstlast) de telle sorte que tous les éléments pour lesquels le prédicat p retourne true précèdent tous les éléments pour lesquels le prédicat p retourne false. L'ordre relatif des éléments n'est pas conservé.
2) Identique à (1), mais exécuté selon policy.
Cette surcharge participe à la résolution de surcharge uniquement si la valeur de l'expression suivante est true :

std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>

(jusqu'à C++20)

std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>

(depuis C++20)

Si le type de *first n'est pas Swappable(jusqu'à C++11)ForwardIt n'est pas ValueSwappable(depuis C++11), le comportement est indéfini.

Paramètres

first, last - la paire d'itérateurs définissant la plage d'éléments à réordonner
policy - la politique d'exécution à utiliser
p - prédicat unaire qui retourne ​true si l'élément doit être ordonné avant les autres éléments.

L'expression p(v) doit être convertible en bool pour tout argument v de type (éventuellement const) VT, où VT est le type valeur de ForwardIt, indépendamment de la catégorie de valeur, et ne doit pas modifier v. Ainsi, un type de paramètre VT&n'est pas autorisé, pas plus que VT sauf si pour VT un déplacement équivaut à une copie(depuis C++11). ​

Exigences de type
-
ForwardIt doit satisfaire aux exigences de LegacyForwardIterator.
-
UnaryPred doit satisfaire aux exigences de Predicate.

Valeur de retour

Itérateur vers le premier élément du deuxième groupe.

Complexité

Étant donné N = std::distance(first, last) :

1) Exactement N applications de p.
Au plus N/2 échanges si ForwardIt satisfait aux exigences de LegacyBidirectionalIterator, et au plus N échanges sinon.
2) O(N) applications de p.
O(N·log(N)) échanges.

Exceptions

La surcharge avec un paramètre de modèle nommé ExecutionPolicy signale les erreurs comme suit :

  • Si l'exécution d'une fonction invoquée dans le cadre de l'algorithme lève une exception et que ExecutionPolicy est l'une des politiques standard, std::terminate est appelé. Pour toute autre ExecutionPolicy, le comportement est défini par l'implémentation.
  • Si l'algorithme ne parvient pas à allouer de la mémoire, std::bad_alloc est levée.

Implémentation possible

Implémente la surcharge (1) en préservant la compatibilité C++11.

template<class ForwardIt, class UnaryPred>
ForwardIt partition(ForwardIt first, ForwardIt last, UnaryPred p)
{
    first = std::find_if_not(first, last, p);
    if (first == last)
        return first;
    
    for (auto i = std::next(first); i != last; ++i)
        if (p(*i))
        {
            std::iter_swap(i, first);
            ++first;
        }
    
    return first;
}

Exemple

#include <algorithm>
#include <forward_list>
#include <iostream>
#include <iterator>
#include <vector>

template<class ForwardIt>
void quicksort(ForwardIt first, ForwardIt last)
{
    if (first == last)
        return;
    
    auto pivot = *std::next(first, std::distance(first, last) / 2);
    auto middle1 = std::partition(first, last, [pivot](const auto& em)
    {
        return em < pivot;
    });
    auto middle2 = std::partition(middle1, last, [pivot](const auto& em)
    {
        return !(pivot < em);
    });
    
    quicksort(first, middle1);
    quicksort(middle2, last);
}

int main()
{
    std::vector<int> v{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    std::cout << "Original vector: ";
    for (int elem : v)
        std::cout << elem << ' ';
    
    auto it = std::partition(v.begin(), v.end(), [](int i) {return i % 2 == 0;});
    
    std::cout << "\nPartitioned vector: ";
    std::copy(std::begin(v), it, std::ostream_iterator<int>(std::cout, " "));
    std::cout << "* ";
    std::copy(it, std::end(v), std::ostream_iterator<int>(std::cout, " "));
    
    std::forward_list<int> fl {1, 30, -4, 3, 5, -4, 1, 6, -8, 2, -5, 64, 1, 92};
    std::cout << "\nUnsorted list: ";
    for (int n : fl)
        std::cout << n << ' ';
    
    quicksort(std::begin(fl), std::end(fl));
    std::cout << "\nSorted using quicksort: ";
    for (int fi : fl)
        std::cout << fi << ' ';
    std::cout << '\n';
}

Sortie possible :

Original vector: 0 1 2 3 4 5 6 7 8 9 
Partitioned vector: 0 8 2 6 4 * 5 3 7 1 9 
Unsorted list: 1 30 -4 3 5 -4 1 6 -8 2 -5 64 1 92 
Sorted using quicksort: -8 -5 -4 -4 1 1 1 2 3 5 6 30 64 92

Rapports de défauts

Les rapports de défauts suivants, modifiant le comportement, ont été appliqués rétroactivement aux normes C++ précédemment publiées.

DR Appliqué à Comportement tel que publié Comportement correct
LWG 498 C++98 std::partition first devait être
lastLegacyBidirectionalIteratorseulement requis d'être
LegacyForwardIterator
LWG 2150
C++98 std::partition était seulement requis de placer un élément
satisfaisant p avant un élément ne satisfaisant pas p
a corrigé
l'exigence

Voir aussi

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