std::next_permutation
| 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.
operator<(hasta C++20)std::less{}(desde C++20).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:
Si bien la firma no necesita tener |
| 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):
| N |
| 2 |
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
(C++11) |
determina si una secuencia es una permutación de otra secuencia (plantilla de función & objeto función de algoritmo) |
(C++20) |
|
| 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) | |
(C++20) |
|
(C++20) |
genera la siguiente permutación lexicográfica más grande de un rango de elementos (objeto función de algoritmo) |