J'étais curieux de savoir comment std:next_permutation
a été mis en œuvre, j'ai donc extrait le gnu libstdc++ 4.7
et a nettoyé les identifiants et le formatage pour produire la démo suivante...
#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()));
}
Le résultat est conforme aux attentes : http://ideone.com/4nZdx
Mes questions sont les suivantes : Comment cela fonctionne-t-il ? Quelle est la signification de i
, j
et k
? Quelle valeur ont-ils aux différents moments de l'exécution ? Qu'est-ce que l'esquisse d'une preuve de sa justesse ?
Il est clair qu'avant d'entrer dans la boucle principale, il ne vérifie que les cas triviaux de liste à 0 ou 1 élément. A l'entrée de la boucle principale, i pointe sur le dernier élément (pas un élément après la fin) et la liste a au moins 2 éléments.
Que se passe-t-il dans le corps de la boucle principale ?
1 votes
Comment avez-vous extrait ce morceau de code ? Quand j'ai vérifié #include <algorithm>, le code était complètement différent et comportait plus de fonctions.
0 votes
Je viens de remarquer qu'il n'y a pas de clause de retour au bas de cette fonction, est-ce une bonne pratique ? Pourquoi ne renvoie-t-elle pas false ?
1 votes
@Jeff : Le
while (true)
est une boucle infinie, la fonction ne retourne que via les déclarations de retour internes que la boucle contient.