Namensräume
Varianten
Aktionen

std::prev_permutation

Von cppreference.com
< cpp‎ | algorithm
 
 
Algorithmenbibliothek
Beschränkte Algorithmen und Algorithmen für Bereiche (C++20)
Beschränkte Algorithmen, z.B. ranges::copy, ranges::sort, ...
Ausführungsrichtlinien (C++17)
Nicht-modifizierende Sequenzoperationen
Stapeloperationen
(C++17)
Suchoperationen
(C++11)                (C++11)(C++11)

Modifizierende Sequenzoperationen
Kopieroperationen
(C++11)
(C++11)
Tauschoperationen
Transformationsoperationen
Generierungsoperationen
Entfernungsoperationen
Ordnungsändernde Operationen
(bis C++17)(C++11)
(C++20)(C++20)
Stichprobenoperationen
(C++17)

Sortier- und verwandte Operationen
Partitionierungsoperationen
Sortieroperationen
Binäre Suchoperationen
(auf partitionierten Bereichen)
Mengenoperationen (auf sortierten Bereichen)
Zusammenführungsoperationen (auf sortierten Bereichen)
Heapoperationen
Minimum/Maximum-Operationen
(C++11)
(C++17)
Lexikographische Vergleichsoperationen
Permutationsoperationen
prev_permutation

C-Bibliothek
Numerische Operationen
Operationen auf uninitialisiertem Speicher
 
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 [firstlast) in die vorherige Permutation. Gibt true zurück, wenn eine solche Permutation existiert, andernfalls transformiert der Bereich in die letzte Permutation (als ob durch std::sort gefolgt von std::reverse) und gibt false zurück.

1) Die Menge aller Permutationen wird lexikographisch in Bezug auf operator<(bis C++20)std::less{}(seit C++20) geordnet.
2) Die Menge aller Permutationen wird lexikographisch in Bezug auf comp geordnet.

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

Inhalt

[edit] Parameter

first, last - das Iteratorenpaar, das den Bereich der zu permutierenden Elemente definiert
comp - Ein Vergleichsfunktions-Objekt (d.h. ein Objekt, das die Anforderungen an Compare erfüllt), das true zurückgibt, wenn das erste Argument *weniger* als das zweite ist.

Die Signatur der Vergleichsfunktion sollte äquivalent zu Folgendem sein

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

Obwohl die Signatur nicht const& haben muss, darf die Funktion die übergebenen Objekte nicht modifizieren und muss alle Werte vom Typ (möglicherweise const) Type1 und Type2 unabhängig von der Wertkategorie akzeptieren (daher ist Type1& nicht erlaubt, und auch nicht Type1, es sei denn, für Type1 ist ein Move äquivalent zu einer Kopie(seit C++11)).
Die Typen Type1 und Type2 müssen so beschaffen sein, dass ein Objekt vom Typ BidirIt dereferenziert und dann implizit in beide konvertiert werden kann.

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

[edit] Rückgabewert

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

[edit] Ausnahmen

Alle Ausnahmen, die von Iterator-Operationen oder dem Vertauschen von Elementen geworfen werden.

[edit] Komplexität

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

1,2) Höchstens
N
2
Vertauschungen.

[edit] 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;
        }
    }
}

[edit] Anmerkungen

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

Implementierungen (z.B. MSVC STL) können Vektorisierung aktivieren, wenn der Iteratortyp LegacyContiguousIterator erfüllt und das Vertauschen seines Wertetyps weder eine nicht-triviale spezielle Member-Funktion noch eine über ADL gefundene swap-Funktion aufruft.

[edit] Beispiel

Der folgende Code gibt alle sechs Permutationen des Strings "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

[edit] Siehe auch

bestimmt, ob eine Sequenz eine Permutation einer anderen Sequenz ist
(Funktionsvorlage) [editieren]
erzeugt die nächstgrößere lexikographische Permutation eines Bereichs von Elementen
(Funktionsvorlage) [editieren]
erzeugt die nächstkleinere lexikographische Permutation eines Bereichs von Elementen
(Algorithmus-Funktionsobjekt)[bearbeiten]