Tenía curiosidad por saber cómo std:next_permutation
se implementó, así que extraje la gnu libstdc++ 4.7
versión y desinfecte los identificadores y el formato para producir la siguiente demostración ...
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
template<typename It>
bool next_permutation(It begin, It end)
{
if (begin == end)
return false;
It i = begin;
++i;
if (i == end)
return false;
i = end;
--i;
while (true)
{
It j = i;
--i;
if (*i < *j)
{
It k = end;
while (!(*i < *--k))
/* pass */;
iter_swap(i, k);
reverse(j, end);
return true;
}
if (i == begin)
{
reverse(begin, end);
return false;
}
}
}
int main()
{
vector<int> v = { 1, 2, 3, 4 };
do
{
for (int i = 0; i < 4; i++)
{
cout << v[i] << " ";
}
cout << endl;
}
while (::next_permutation(v.begin(), v.end()));
}
El resultado es el esperado: http://ideone.com/4nZdx
Mis preguntas son: ¿Cómo funciona? ¿Cuál es el significado de i
, j
y k
? ¿Qué valor tienen en las diferentes partes de la ejecución? ¿Qué es un bosquejo de una prueba de su corrección?
Claramente, antes de ingresar al ciclo principal, solo verifica los casos triviales de lista de elementos 0 o 1. En la entrada del bucle principal, i está apuntando al último elemento (no a un final pasado) y la lista tiene al menos 2 elementos.
¿Qué está pasando en el cuerpo del bucle principal?