c++ permutation

next permutation c++



¿Por qué next_permutation omite algunas permutaciones? (4)

Como se indica en algunas de las respuestas anteriores, si desea utilizar el valor de retorno bool de std::next_permutation para detener las iteraciones, debe asegurarse de que comienza desde una permutación "ordenada". De lo contrario, su ciclo terminará prematuramente.

Sin embargo, esto no es absolutamente necesario.

Las permutaciones enumeradas a través de std::next_permutation forman una secuencia cíclica sin un principio o un final, lo que significa que puede llamar a std::next_permutation indefinida y recorrerá la misma secuencia de 120 permutaciones una y otra vez. Esto significa que puede comenzar desde cualquier permutación en ese ciclo. Solo tiene que recordar su permutación inicial y observar el momento en que esta permutación aparezca nuevamente. En el mismo momento en que llegas a tu permutación original, la iteración termina. En su caso, se espera que tome 120 llamadas a std::next_permutation .

Por ejemplo, el siguiente código imprime todas las permutaciones de 5 letras para el conjunto "abcde" a pesar de que comienza desde una completamente arbitraria

std::string start = "cadeb", current = start; do std::cout << current << std::endl; while (std::next_permutation(current.begin(), current.end()), current != start);

Sin embargo, se puede notar que comparar las permutaciones en cada iteración del ciclo es más costoso que usar el valor de retorno de std::next_permutation (que viene "gratis" de las entrañas del algoritmo), así que si está satisfecho con la solución que Pre-ordena la permutación inicial, entonces de hecho es una forma más eficiente de hacerlo.

Alternativamente, si conoce el número exacto de permutaciones en el ciclo (120 en este caso), simplemente puede llamar a std::next_permutation exactamente esa cantidad de veces (como se sugiere en la respuesta de @ Potatoswatter).

¿Por qué esta simple función no genera todas las permutaciones de la cadena de 5 letras ingresada? Creo que debería haber 120 y solo 90.

#include <iostream> #include <vector> #include <algorithm> #include <string> using namespace std; // Creates permutation lists for strings vector<string> createdcombos2(string letters) { vector<string> lettercombos; cout << "Letters are: " << letters << endl; //input string do lettercombos.push_back(letters); while(next_permutation(letters.begin(), letters.end())); cout <<"Letter combos: " << endl; //print out permutations for (auto i : lettercombos) cout << i << endl; cout << endl << lettercombos.size() << endl; //number of permutations return lettercombos; } int main() { string letters = "gnary"; vector<string> lettercombos; lettercombos = createdcombos2(letters); }


El valor bool next_permutation de next_permutation es como una condición de desbordamiento o un bit de acarreo. Es false cuando avanza desde la última permutación a la primera, en orden lexicográfico. Pero sigue avanzando, incondicionalmente.

Si sabe que hay exactamente 120 permutaciones, puede ignorar el valor de retorno y simplemente hacer un bucle ciego:

for ( int i = 0; i != 120; ++ i ) { lettercombos.push_back(letters); next_permutation(letters.begin(), letters.end()); }


Para devolver todas las permutaciones en un bucle hasta que next_permutation devuelva falso, el vector debe ordenarse antes del inicio del bucle. next_permutation devuelve las permutaciones en orden ascendente. Entonces, si comienzas con un vector no clasificado, comenzará en parte a través de la serie de permutaciones.

std::sort(letters.begin(), letters.end()); do lettercombos.push_back(letters); while(next_permutation(letters.begin(), letters.end()));


next_permutation ordenar la entrada, next_permutation devolverá la siguiente permutación en orden lexicográfico. Debido a que la permutación de entrada: "gnary" es lexicográficamente "más grande" que una permutación como "enojada" , esas permutaciones "más pequeñas" nunca se alcanzarán.

Puedes ordenar la cadena usando std::sort()