Bonjour à tous je me suis à mon tour, penché sur cette question et je suis tombé sur ce post.
J'ai donc pris mon mal en patiente et tenté d'en faire un moi même. ce code est en Action script 2.0 (langage de flash) mais je pense que la syntaxe est proche du C à la déclaration de quelques variables près. j'ai tenté de commenter le code et je demeure ouvert à toute suggestion/optimisation:
//pour connaitre le nombre de combinaisons possibles
function c(k,n){
tot=1;
for(r=n;r>k;r--){tot*=r;}
for(r=(n-k);r>1;r--){tot/=r;}
return(tot);
}
//la fonction suivante retourne un tableau de longueur c(k,n),ou k représente la longueur du tableau passé en //paramètre, contenant pour chaque indice un tableau contenant n elements constituant une combinaison unique
function combi(arr_in,n){
//initialisation du tableau detiné à recevoir une combinaison par indice
//pour les languages n'autorisant pas la création de tableaux de longueur dynamique: //C(k,n)=n!/(k!(n-k)!),cf:fonction donnée plus haut
comb=[];
fini=false;
//initialisation d'un tableau de longueur n destiné à recevoir les n indices du tableau d'entrée reçu en paramètre //constituant un élément de la combinaison en cours
id=Array(n);
//affectation de valeurs croissantes -1 pour le dernier indice
for(cptid=0;cptid<n;cptid++){id[cptid]=cptid;}
id[n-1]=id[n-1]-1;
//l'algorithme avec k fixé prendrait l'allure de k boucles for imbriquées
//j'ai ici simulé un tel comportement par l'utilisation d'une boucle parcourant k avec une structure conditionnelle //testant le non dépassement des indices:
//incrémentation si non dépassement,changement de dimension de la boucle dans la clause else
while(!fini){
exit=false;
for(i=n-1;i>=0 && !exit;i--){
if(id[i]<arr_in.length-n+i){
id[i]++;
exit=true;
}else{
fini=(i==0);
first=true;
for(cpt=(n-i);cpt>0;cpt--){
id[n-cpt]=id[(n-1)-cpt]+((first)?2:1);
first=false;
}
}
}
if(!fini){
//construction du tableau contenant la combinaison en cours
arr_aux=Array(n);
for(cptid=0;cptid<n;cptid++){arr_aux[cptid]=arr_in[id[cptid]];}
//ajout de cette combinaison au tableau en contenant l'intégralité
comb.push(arr_aux);
}
}
return comb;
}
//test de la fonction
trace("["+combi(["A","B","C","D","E","F","G"],5).join("]"+chr(13)+"[")+"]");
voilà ceci fonctionne aussi avec un tableau d'entiers, ou même d'objets
attention, je n'ai pas mis de gestion d'erreur dans le cas ou le tableau serait plus petit que k, sous flash cela retourne un tableau vide, mais génèrera sans doute des erreurs dans un langage tel que C