Namespaces
Variants

std::prev_permutation

Von de.cppreference.net
 
 
Algorithmus-Bibliothek
Eingeschränkte Algorithmen und Algorithmen auf Bereichen (C++20)
Eingeschränkte Algorithmen, z. B. ranges::copy, ranges::sort, ...
Nicht-modifizierende Sequenzoperationen    
Stapeloperationen
(C++17)
Suchoperationen
Modifizierende Sequenzoperationen
Kopieroperationen
(C++11)
(C++11)
Tauschoperationen
Transformationsoperationen
Erzeugungsoperationen
Entfernungsoperationen
Reihenfolge-ändernde Operationen
(bis C++17)(C++11)
(C++20)(C++20)
Stichprobenoperationen
(C++17)

Sortier- und verwandte Operationen
Partitionierungsoperationen
(C++11)    

Sortieroperationen
Binäre Suchoperationen
(auf partitionierten Bereichen)
Mengenoperationen (auf sortierten Bereichen)
Mischoperationen (auf sortierten Bereichen)
Heap-Operationen
Minimum/Maximum-Operationen
(C++11)
(C++17)
Lexikografische Vergleichsoperationen
Permutationsoperationen


 
Definiert in Header <algorithm>
template< class BidirIt >
bool prev_permutation( BidirIt first, BidirIt last );
(1) (constexpr seit C++20)
template< class BidirIt, class Compare >
bool prev_permutation( BidirIt first, BidirIt last, Compare comp );
(2) (constexpr seit C++20)

Transformiert den Bereich [first, last) in die vorherige Permutation. Gibt true zurück, falls eine solche Permutation existiert, andernfalls transformiert es den Bereich in die letzte Permutation (eine absteigende Reihenfolge) und gibt false zurück.

1) Die Menge aller Permutationen ist lexikografisch geordnet bezüglich operator<(bis C++20)std::less{}(seit C++20).
2) Die Menge aller Permutationen ist lexikografisch geordnet bezüglich comp.

Falls der Typ von *first nicht Swappable(bis C++11)BidirIt nicht ValueSwappable(seit C++11) ist, ist das Verhalten undefiniert.

Parameter

first, last - das Paar von Iteratoren, das den Bereich der zu permutierenden Elemente definiert
comp - Vergleichsfunktionsobjekt (d. h. ein Objekt, das die Anforderungen von Compare erfüllt), das true zurückgibt, wenn das erste Argument kleiner als das zweite ist.

Die Signatur der Vergleichsfunktion sollte der folgenden entsprechen:

bool cmp(const Type1& a, const Type2& b);

Während die Signatur nicht const& haben muss, darf die Funktion die ihr übergebenen Objekte nicht ändern und muss alle Werte des Typs (möglicherweise const) Type1 und Type2 unabhängig von der Wertkategorie akzeptieren können (daher ist Type1& nicht erlaubt, ebenso wenig wie Type1, außer wenn für Type1 eine Bewegung einer Kopie gleichkommt(seit C++11)).
Die Typen Type1 und Type2 müssen so sein, dass ein Objekt des Typs BidirIt dereferenziert und dann implizit in beide konvertiert werden kann.

Typanforderungen
-
BidirIt muss die Anforderungen von ValueSwappable und LegacyBidirectionalIterator erfüllen.

Rückgabewert

true, wenn die neue Permutation der alten in lexikografischer Ordnung vorausgeht. false, wenn die erste Permutation erreicht wurde und der Bereich auf die letzte Permutation zurückgesetzt wurde.

Ausnahmen

Jegliche Ausnahmen, die von Iteratoroperationen oder dem Elementtausch ausgelöst werden.

Komplexität

Gegeben N als std::distance(first, last):

1,2) Höchstens
N
2
Vertauschungen.

Mögliche Implementierung

template<class BidirIt>
bool prev_permutation(BidirIt first, BidirIt last)
{
    if (first == last)
        return false;
    BidirIt i = last;
    if (first == --i)
        return false;
    
    while (1)
    {
        BidirIt i1, i2;
        
        i1 = i;
        if (*i1 < *--i)
        {
            i2 = last;
            while (!(*--i2 < *i))
                ;
            std::iter_swap(i, i2);
            std::reverse(i1, last);
            return true;
        }
        
        if (i == first)
        {
            std::reverse(first, last);
            return false;
        }
    }
}

Hinweise

Über die gesamte Sequenz von Permutationen gemittelt, verwenden typische Implementierungen etwa 3 Vergleiche und 1,5 Vertauschungen pro Aufruf.

Implementierungen (z. B. MSVC STL) können die Vektorisierung aktivieren, wenn der Iteratortyp LegacyContiguousIterator erfüllt und das Vertauschen seines Werttyps weder eine nicht-triviale spezielle Memberfunktion noch ADL-gefundenes swap aufruft.

Beispiel

Der folgende Code gibt alle sechs Permutationen der Zeichenkette "cab" in umgekehrter Reihenfolge aus.

#include <algorithm>
#include <iostream>
#include <string>

int main()
{
    std::string s = "cab";
    
    do
    {
        std::cout << s << ' ';
    }
    while (std::prev_permutation(s.begin(), s.end()));
    
    std::cout << s << '\n';
}

Ausgabe:

cab bca bac acb abc cba

Siehe auch

bestimmt, ob eine Sequenz eine Permutation einer anderen Sequenz ist
(Funktionsschablone & Algorithmus-Funktionsobjekt)
erzeugt die nächstgrößere lexikografische Permutation eines Bereichs von Elementen
(Funktionsschablone & Algorithmus-Funktionsobjekt)
erzeugt die nächstkleinere lexikografische Permutation eines Bereichs von Elementen
(Algorithmus-Funktionsobjekt)