Namensräume
Varianten
Aktionen

std::next_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
next_permutation

C-Bibliothek
Numerische Operationen
Operationen auf uninitialisiertem Speicher
 
Definiert in Header <algorithm>
template< class BidirIt >
bool next_permutation( BidirIt first, BidirIt last );
(1) (constexpr seit C++20)
template< class BidirIt, class Compare >
bool next_permutation( BidirIt first, BidirIt last, Compare comp );
(2) (constexpr seit C++20)

Permutiert den Bereich [firstlast) in die nächste Permutation. Gibt true zurück, wenn eine solche "nächste Permutation" existiert; andernfalls transformiert sie den Bereich in die lexikographisch erste Permutation (als ob durch std::sort) und gibt false zurück.

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

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 LegacyBidirectionalIterator erfüllen.

[edit] Rückgabewert

true, wenn die neue Permutation lexikographisch größer als die alte ist. false, wenn die letzte Permutation erreicht wurde und der Bereich auf die erste Permutation zurückgesetzt wurde.

[edit] Komplexität

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

1,2) Höchstens
N
2
Vertauschungen.

[edit] Ausnahmen

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

[edit] Mögliche Implementierung

template<class BidirIt>
bool next_permutation(BidirIt first, BidirIt last)
{
    auto r_first = std::make_reverse_iterator(last);
    auto r_last = std::make_reverse_iterator(first);
    auto left = std::is_sorted_until(r_first, r_last);
 
    if (left != r_last)
    {
        auto right = std::upper_bound(r_first, left, *left);
        std::iter_swap(left, right);
    }
 
    std::reverse(left.base(), last);
    return left != r_last;
}

[edit] Anmerkungen

Durchschnittlich über die gesamte Sequenz von Permutationen hinweg 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 drei Permutationen des Strings "aba" aus.

#include <algorithm>
#include <iostream>
#include <string>
 
int main()
{
    std::string s = "aba";
 
    do
    {
        std::cout << s << '\n';
    }
    while (std::next_permutation(s.begin(), s.end()));
 
    std::cout << s << '\n';
}

Ausgabe

aba
baa
aab

[edit] Siehe auch

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