Namespaces
Variants

std::prev_permutation

De es.cppreference.net
 
 
Biblioteca de algoritmos
Algoritmos restringidos y algoritmos sobre rangos (C++20)
Algoritmos restringidos, ej. ranges::copy, ranges::sort, ...
Operaciones de secuencia no modificantes    
Operaciones por lotes
(C++17)
Operaciones de búsqueda
Operaciones de secuencia modificantes
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)

Ordenación y operaciones relacionadas
Operaciones de partición
(C++11)    

Operaciones de ordenación
Operaciones de búsqueda binaria
(en rangos particionados)
Operaciones de conjuntos (en rangos ordenados)
Operaciones de mezcla (en rangos ordenados)
Operaciones de montículo
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 prev_permutation( BidirIt first, BidirIt last );
(1) (constexpr desde C++20)
template< class BidirIt, class Compare >
bool prev_permutation( BidirIt first, BidirIt last, Compare comp );
(2) (constexpr desde C++20)

Transforma el rango [first, last) en la permutación previa. Devuelve true si dicha permutación existe; en caso contrario, transforma el rango en la última permutación (un orden descendente) 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 la siguiente:

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

Aunque 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 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 ValueSwappable y LegacyBidirectionalIterator.

Valor de retorno

true si la nueva permutación precede a la anterior en orden lexicográfico. false si se alcanzó la primera permutación y el rango se restableció a la última permutación.

Excepciones

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

Complejidad

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

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

Posible implementación

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

Notas

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

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

Ejemplo

El siguiente código imprime las seis permutaciones de la cadena "cab" en orden inverso.

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

Salida:

cab bca bac acb abc cba

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 mayor de un rango de elementos
(plantilla de función & objeto función de algoritmo)
genera la siguiente permutación lexicográfica menor de un rango de elementos
(objeto función de algoritmo)