Namespaces
Variants

std::ranges::prev_permutation, std::ranges::prev_permutation_result

Depuis fr.cppreference.net
 
 
Bibliothèque d'algorithmes
Algorithmes contraints et algorithmes sur les plages (C++20)
Algorithmes contraints, ex. ranges::copy, ranges::sort, ...
Opérations de séquence non modifiantes    
Opérations par lots
(C++17)
Opérations de recherche
Opérations de séquence modifiantes
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
(until C++17)(C++11)
(C++20)(C++20)
Opérations d'échantillonnage
(C++17)

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

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


 
Algorithmes contraints
Tous les noms de ce menu appartiennent à l'espace de noms std::ranges
Opérations de séquence non modifiantes
Opérations de séquence modifiantes
Opérations de partitionnement
Opérations de tri
Opérations de recherche binaire (sur plages triées)
       
       
Opérations d'ensemble (sur plages triées)
Opérations sur les tas
Opérations minimum/maximum
       
       
Opérations de permutation
Opérations de pliage
Opérations sur le stockage non initialisé
Types de retour
 
Défini dans l'en-tête <algorithm>
Signature d'appel
template< std::bidirectional_iterator I, std::sentinel_for<I> S,
          class Comp = ranges::less, class Proj = std::identity >
requires std::sortable<I, Comp, Proj>
constexpr prev_permutation_result<I>
    prev_permutation( I first, S last, Comp comp = {}, Proj proj = {} );
(1) (depuis C++20)
template< ranges::bidirectional_range R, class Comp = ranges::less,
          class Proj = std::identity >
requires std::sortable<ranges::iterator_t<R>, Comp, Proj>
constexpr prev_permutation_result<ranges::borrowed_iterator_t<R>>
    prev_permutation( R&& r, Comp comp = {}, Proj proj = {} );
(2) (depuis C++20)
Type d'aide
template< class I >
using prev_permutation_result = ranges::in_found_result<I>;
(3) (depuis C++20)
1) Transforme la plage [firstlast) en la précédente permutation, où l'ensemble de toutes les permutations est ordonné lexicographiquement par rapport à l'objet fonction de comparaison binaire comp et l'objet fonction de projection proj.
Retourne :
  • {last, true} si la permutation "précédente" existe. Sinon,
  • {last, false}, et transforme la plage en la permutation lexicographiquement dernière (un ordre décroissant)
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 semblables à des fonctions décrites sur cette page sont objets fonctions d'algorithme (informellement appelées niebloids), c'est-à-dire :

Paramètres

first, last - la paire itérateur-sentinelle définissant la plage des éléments à "permuter"
r - la range des éléments à "permuter"
comp - l'objet-fonction de comparaison FunctionObject qui renvoie true si le premier argument est inférieur au second
proj - projection à appliquer aux éléments

Valeur de retour

1) ranges :: prev_permutation_result < I > { last, true } si la nouvelle permutation est lexicographiquement inférieure à l'ancienne. ranges :: prev_permutation_result < I > { last, false } si la première permutation a été atteinte et que la plage a été réinitialisée à la dernière permutation.
2) Identique à (1) sauf que le type de retour est ranges :: prev_permutation_result < ranges:: borrowed_iterator_t < R >> .

Exceptions

Toute exception levée par les opérations sur les itérateurs ou l'échange d'éléments.

Complexité

Au maximum N / 2 échanges, où N est ranges:: distance ( first, last ) dans le cas (1) ou ranges:: distance ( r ) dans le cas (2) . En moyenne sur l'ensemble de la séquence de permutations, les implémentations typiques utilisent environ 3 comparaisons et 1,5 échanges par appel.

Notes

Les implémentations (par exemple MSVC STL ) peuvent activer la vectorisation lorsque le type d'itérateur modélise contiguous_iterator et que l'échange de son type de valeur n'appelle ni fonction membre spéciale non triviale ni ADL -trouvée swap .

Implémentation possible

struct prev_permutation_fn
{
    template<std::bidirectional_iterator I, std::sentinel_for<I> S,
             class Comp = ranges::less, class Proj = std::identity>
    requires std::sortable<I, Comp, Proj>
    constexpr ranges::prev_permutation_result<I>
        operator()(I first, S last, Comp comp = {}, Proj proj = {}) const
    {
        // vérifier que la séquence a au moins deux éléments
        if (first == last)
            return {std::move(first), false};
        auto i{first};
        ++i;
        if (i == last)
            return {std::move(i), false};
        auto i_last{ranges::next(first, last)};
        i = i_last;
        --i;
        // boucle principale de "permutation"
        for (;;)
        {
            auto i1{i};
            --i;
            if (std::invoke(comp, std::invoke(proj, *i1), std::invoke(proj, *i)))
            {
                auto j{i_last};
                while (!std::invoke(comp, std::invoke(proj, *--j), std::invoke(proj, *i)))
                    ;
                ranges::iter_swap(i, j);
                ranges::reverse(i1, last);
                return {std::move(i_last), true};
            }
            // l'espace de "permutation" est épuisé
            if (i == first)
            {
                ranges::reverse(first, last);
                return {std::move(i_last), false};
            }
        }
    }
    template<ranges::bidirectional_range R, class Comp = ranges::less,
             class Proj = std::identity>
    requires std::sortable<ranges::iterator_t<R>, Comp, Proj>
    constexpr ranges::prev_permutation_result<ranges::borrowed_iterator_t<R>>
        operator()(R&& r, Comp comp = {}, Proj proj = {}) const
    {
        return (*this)(ranges::begin(r), ranges::end(r),
                       std::move(comp), std::move(proj));
    }
};
inline constexpr prev_permutation_fn prev_permutation {};

Exemple

#include <algorithm>
#include <array>
#include <compare>
#include <functional>
#include <iostream>
#include <string>
struct S
{
    char c{};
    int i{};
    auto operator<=>(const S&) const = default;
    friend std::ostream& operator<<(std::ostream& os, const S& s)
    {
        return os << "{'" << s.c << "', " << s.i << "}";
    }
};
auto print = [](auto const& v, char term = ' ')
{
    std::cout << "{ ";
    for (const auto& e : v)
        std::cout << e << ' ';
    std::cout << '}' << term;
};
int main()
{
    std::cout << "Générer toutes les permutations (cas des itérateurs) :\n";
    std::string s{"cba"};
    do print(s);
    while (std::ranges::prev_permutation(s.begin(), s.end()).found);
    std::cout << "\nGénérer toutes les permutations (cas des plages) :\n";
    std::array a{'c', 'b', 'a'};
    do print(a);
    while (std::ranges::prev_permutation(a).found);
    std::cout << "\nGénérer toutes les permutations en utilisant un comparateur :\n";
    using namespace std::literals;
    std::array z{"▁"s, "▄"s, "█"s};
    do print(z);
    while (std::ranges::prev_permutation(z, std::greater()).found);
    std::cout << "\nGénérer toutes les permutations en utilisant une projection :\n";
    std::array<S, 3> r{S{'C',1}, S{'B',2}, S{'A',3}};
    do print(r, '\n');
    while (std::ranges::prev_permutation(r, {}, &S::c).found);
}

Sortie :

Generate all permutations (iterators case):
{ c b a } { c a b } { b c a } { b a c } { a c b } { a b c }
Generate all permutations (range case):
{ c b a } { c a b } { b c a } { b a c } { a c b } { a b c }
Generate all permutations using comparator:
{ ▁ ▄ █ } { ▁ █ ▄ } { ▄ ▁ █ } { ▄ █ ▁ } { █ ▁ ▄ } { █ ▄ ▁ }
Generate all permutations using projection:
{ {'C', 1} {'B', 2} {'A', 3} }
{ {'C', 1} {'A', 3} {'B', 2} }
{ {'B', 2} {'C', 1} {'A', 3} }
{ {'B', 2} {'A', 3} {'C', 1} }
{ {'A', 3} {'C', 1} {'B', 2} }
{ {'A', 3} {'B', 2} {'C', 1} }

Voir aussi

génère la permutation lexicographique suivante plus grande d'une plage d'éléments
(objet fonction d'algorithme)
détermine si une séquence est une permutation d'une autre séquence
(objet fonction d'algorithme)
génère la permutation lexicographique suivante plus grande d'une plage d'éléments
(modèle de fonction & objet fonction d'algorithme)
génère la permutation lexicographique suivante plus petite d'une plage d'éléments
(modèle de fonction)
détermine si une séquence est une permutation d'une autre séquence
(modèle de fonction & objet fonction d'algorithme)