Namespaces
Variants

std::next_permutation

De es.cppreference.net
 
 
Biblioteca de algoritmos
Algoritmos restringidos y algoritmos sobre rangos (C++20)
Algoritmos restringidos, p. ej. ranges::copy, ranges::sort, ...
Operaciones de secuencia no modificadoras    
Operaciones por lotes
(C++17)
Operaciones de búsqueda
Operaciones de secuencia modificadoras
Operaciones de copia
(C++11)
(C++11)
Operaciones de intercambio
Operaciones de transformación
Operaciones de generación
Operaciones de eliminación
Operaciones de cambio de orden
(hasta C++17)(C++11)
(C++20)(C++20)
Operaciones de muestreo
(C++17)

Operaciones de ordenamiento y relacionadas
Operaciones de particionamiento
(C++11)    

Operaciones de ordenamiento
Operaciones de búsqueda binaria
(en rangos particionados)
Operaciones de conjuntos (en rangos ordenados)
Operaciones de fusión (en rangos ordenados)
Operaciones de montón
Operaciones de mínimo/máximo
(C++11)
(C++17)
Operaciones de comparación lexicográfica
Operaciones de permutación


 
Definido en el encabezado <algorithm>
template< class BidirIt >
bool next_permutation( BidirIt first, BidirIt last );
(1) (constexpr desde C++20)
template< class BidirIt, class Compare >
bool next_permutation( BidirIt first, BidirIt last, Compare comp );
(2) (constexpr desde C++20)

Permuta el rango [first, last) en la siguiente permutación. Devuelve true si existe dicha "siguiente permutación"; en caso contrario, transforma el rango en la primera permutación lexicográfica (un orden ascendente) y devuelve false.

1) El conjunto de todas las permutaciones está ordenado lexicográficamente con respecto a operator<(hasta C++20)std::less{}(desde C++20).
2) El conjunto de todas las permutaciones está ordenado lexicográficamente con respecto a comp.

Si el tipo de *first no es Swappable(hasta C++11)BidirIt no es ValueSwappable(desde C++11), el comportamiento no está definido.

Parámetros

first, last - el par de iteradores que definen el rango de elementos a permutar
comp - objeto función de comparación (es decir, un objeto que satisface los requisitos de Compare) que devuelve true si el primer argumento es menor que el segundo.

La firma de la función de comparación debe ser equivalente a lo siguiente:

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

Si bien la firma no necesita tener const&, la función no debe modificar los objetos que se le pasan y debe poder aceptar todos los valores de tipo (posiblemente const) Type1 y Type2 independientemente de la categoría de valor (por lo tanto, Type1& no está permitido, ni tampoco Type1 a menos que para Type1 un movimiento sea equivalente a una copia(desde C++11)).
Los tipos Type1 y Type2 deben ser tales que un objeto de tipo BidirIt pueda ser desreferenciado y luego convertido implícitamente a ambos.

Requisitos de tipo
-
BidirIt debe cumplir los requisitos de LegacyBidirectionalIterator.

Valor de retorno

true si la nueva permutación es lexicográficamente mayor que la anterior. false si se alcanzó la última permutación y el rango se restableció a la primera permutación.

Complejidad

Dado N como std::distance(first, last):

1,2) Como máximo
N
2
intercambios.

Excepciones

Cualquier excepción lanzada por operaciones de iterador o el intercambio de elementos.

Posible implementación

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;
}

Notas

Promediando sobre toda la secuencia de permutaciones, las implementaciones típicas usan alrededor de 3 comparaciones y 1.5 intercambios por llamada.

Las implementaciones (p. ej. MSVC STL) pueden habilitar la vectorización cuando el tipo de iterador satisface LegacyContiguousIterator e intercambiar su tipo de valor no llama a ninguna función miembro especial no trivial ni a ADL encontrado swap.

Ejemplo

El siguiente código imprime todas las permutaciones de una cadena.

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

int main()
{
    std::string s = "ABBA";
    std::sort(s.begin(), s.end());
    
    do
        std::cout << s << '\n';
    while (std::next_permutation(s.begin(), s.end()));

    assert(std::is_sorted(s.begin(), s.end()));
}

Salida:

AABB
ABAB
ABBA
BAAB
BABA
BBAA

Véase también

determina si una secuencia es una permutación de otra secuencia
(plantilla de función & objeto función de algoritmo)
genera la siguiente permutación lexicográfica más pequeña de un rango de elementos
(plantilla de función & objeto función de algoritmo)
genera la siguiente permutación lexicográfica más grande de un rango de elementos
(objeto función de algoritmo)