Algorithme pour générer toutes les permutations possibles d’une liste?

Disons que j’ai une liste de n éléments, je sais qu’il y en a n! les moyens possibles pour commander ces éléments. Qu’est-ce qu’un algorithme pour générer toutes les commandes possibles de cette liste? Exemple, j’ai la liste [a, b, c]. L’algorithme renverrait [[a, b, c], [a, c, b,], [b, a, c], [b, c, a], [c, a, b], [c, b , une]].

Je lis ceci ici http://en.wikipedia.org/wiki/Permutation#Algorithms_to_generate_permutations

Mais Wikipedia n’a jamais été bon à expliquer. Je ne comprends pas grand chose.

Fondamentalement, pour chaque élément de gauche à droite, toutes les permutations des éléments restants sont générées (et chaque élément est ajouté aux éléments actuels). Cela peut être fait de manière récursive (ou itérative si vous aimez la douleur) jusqu’à ce que le dernier élément soit atteint, auquel cas il n’y a qu’un seul ordre possible.

Donc, avec la liste [1,2,3,4], toutes les permutations qui commencent par 1 sont générées, puis toutes les permutations qui commencent par 2, puis 3 puis 4.

Cela réduit effectivement le problème de trouver des permutations d’une liste de quatre éléments à une liste de trois éléments. Après avoir réduit à 2 puis à 1 listes d’éléments, elles seront toutes trouvées.
Exemple de permutation de processus utilisant 3 boules colorées:
Balles de couleurs rouges, vertes et bleues ordonnées image de permutations ( https://en.wikipedia.org/wiki/Permutation#/media/File:Permutations_RGB.svghttps://commons.wikimedia.org/wiki/File:Permutations_RGB.svg )

Voici un algorithme en Python qui fonctionne en place sur un tableau:

def permute(xs, low=0): if low + 1 >= len(xs): yield xs else: for p in permute(xs, low + 1): yield p for i in range(low + 1, len(xs)): xs[low], xs[i] = xs[i], xs[low] for p in permute(xs, low + 1): yield p xs[low], xs[i] = xs[i], xs[low] for p in permute([1, 2, 3, 4]): print p 

Vous pouvez essayer le code par vous-même ici: http://repl.it/J9v

La réponse de Wikipedia pour “ordre lexicographique” me semble parfaitement explicite dans le style des livres de recettes. Il cite une origine du 14ème siècle pour l’algorithme!

Je viens d’écrire une implémentation rapide dans l’algorithme de Java de Wikipedia comme vérification et ce n’était pas un problème. Mais ce que vous avez dans votre Q comme exemple n’est PAS “lister toutes les permutations”, mais “une LISTE de toutes les permutations”, donc Wikipédia ne vous aidera pas beaucoup. Vous avez besoin d’un langage dans lequel des listes de permutations peuvent être construites. Et croyez-moi, les listes de quelques milliards de long ne sont généralement pas traitées dans des langages impératifs. Vous voulez vraiment un langage de programmation fonctionnel non ssortingct, dans lequel les listes sont un object de premier ordre, pour sortir tout ce qui ne rapproche pas la machine de la mort de l’univers.

C’est facile. En standard Haskell ou tout langage moderne de PF:

 -- perms of a list perms :: [a] -> [ [a] ] perms (a:as) = [bs ++ a:cs | perm <- perms as, (bs,cs) <- splits perm] perms [] = [ [] ] 

et

 -- ways of splitting a list into two parts splits :: [a] -> [ ([a],[a]) ] splits [] = [ ([],[]) ] splits (a:as) = ([],a:as) : [(a:bs,cs) | (bs,cs) <- splits as] 

Il y a déjà beaucoup de bonnes solutions ici, mais j’aimerais partager comment j’ai résolu ce problème par moi-même et j’espère que cela pourrait être utile pour quelqu’un qui voudrait aussi trouver sa propre solution.

Après quelques reflections sur le problème, je suis arrivé à deux conclusions suivantes:

  1. Pour la liste L de taille n il y aura un nombre égal de solutions commençant par L 1 , L 2 … L n éléments de la liste. Depuis au total il y a n! permutations de la liste de taille n , on obtient n! / n = (n-1)! n! / n = (n-1)! permutations dans chaque groupe.
  2. La liste des 2 éléments n’a que 2 permutations => [a,b] et [b,a] .

En utilisant ces deux idées simples, j’ai dérivé l’algorithme suivant:

 permute array if array is of size 2 return first and second element as new array return second and first element as new array else for each element in array new subarray = array with excluded element return element + permute subarray 

Voici comment je l’ai implémenté en C #:

 public IEnumerable> Permutate(List input) { if (input.Count == 2) // this are permutations of array of size 2 { yield return new List(input); yield return new List {input[1], input[0]}; } else { foreach(T elem in input) // going through array { var rlist = new List(input); // creating subarray = array rlist.Remove(elem); // removing element foreach(List retlist in Permutate(rlist)) { retlist.Insert(0,elem); // inserting the element at pos 0 yield return retlist; } } } } 

Comme WhirlWind l’a dit, vous commencez au début.

Vous échangez le curseur avec chaque valeur restante, y compris le curseur lui-même, ce sont toutes de nouvelles instances (j’ai utilisé int[] et array.clone() dans l’exemple).

Effectuez ensuite des permutations sur toutes ces différentes listes, en vous assurant que le curseur est un à droite.

Lorsqu’il n’y a plus de valeurs restantes (le curseur est à la fin), imprimez la liste. C’est la condition d’arrêt.

 public void permutate(int[] list, int pointer) { if (pointer == list.length) { //stop-condition: print or process number return; } for (int i = pointer; i < list.length; i++) { int[] permutation = (int[])list.clone();. permutation[pointer] = list[i]; permutation[i] = list[pointer]; permutate(permutation, pointer + 1); } } 

Récursive demande toujours un certain effort mental pour se maintenir. Et pour les gros nombres, la factorielle est facilement énorme et le débordement de stack sera facilement un problème.

Pour les petits nombres (3 ou 4, le plus souvent rencontrés), les boucles multiples sont assez simples et directes. Il est regrettable que les réponses avec des boucles n’aient pas été votées.

Commençons par l’énumération (plutôt que la permutation). Lisez simplement le code en tant que pseudo-code perl.

 $foreach $i1 in @list $foreach $i2 in @list $foreach $i3 in @list print "$i1, $i2, $i3\n" 

L’énumération est plus fréquente que la permutation, mais si la permutation est nécessaire, ajoutez simplement les conditions:

 $foreach $i1 in @list $foreach $i2 in @list $if $i2==$i1 next $foreach $i3 in @list $if $i3==$i1 or $i3==$i2 next print "$i1, $i2, $i3\n" 

Maintenant, si vous avez vraiment besoin d’une méthode générale pour les grandes listes, nous pouvons utiliser la méthode radix. Tout d’abord, considérons le problème d’énumération:

 $n=@list my @radix $for $i=0:$n $radix[$i]=0 $while 1 my @temp $for $i=0:$n push @temp, $list[$radix[$i]] print join(", ", @temp), "\n" $call radix_increment subcode: radix_increment $i=0 $while 1 $radix[$i]++ $if $radix[$i]==$n $radix[$i]=0 $i++ $else last $if $i>=$n last 

L’incrément de base est essentiellement le nombre (dans la base du nombre d’éléments de la liste).

Maintenant, si vous avez besoin de permutaion, ajoutez simplement les vérifications à l’intérieur de la boucle:

 subcode: check_permutation my @check my $flag_dup=0 $for $i=0:$n $check[$radix[$i]]++ $if $check[$radix[$i]]>1 $flag_dup=1 last $if $flag_dup next 

Edit: Le code ci-dessus devrait fonctionner, mais pour la permutation, radix_increment pourrait être un gaspillage. Donc, si le temps est un problème pratique, nous devons changer radix_increment en permute_inc:

 subcode: permute_init $for $i=0:$n $radix[$i]=$i subcode: permute_inc $max=-1 $for $i=$n:0 $if $max<$radix[$i] $max=$radix[$i] $else $for $j=$n:0 $if $radix[$j]>$radix[$i] $call swap, $radix[$i], $radix[$j] break $j=$i+1 $k=$n-1 $while $j<$k $call swap, $radix[$j], $radix[$k] $j++ $k-- break $if $i<0 break 

Bien sûr, ce code est logiquement plus complexe, je pars pour l'exercice du lecteur.

Si quelqu’un se demande comment faire en permutation en javascript.

Idée / pseudocode

  1. choisir un élément à la fois
  2. permuter le rest de l’élément, puis append l’élément sélectionné à la totalité de la permutation

par exemple. ‘a’ + permute (bc). permute de bc serait bc & cb. Maintenant, ajoutez ces deux donner abc, acb. de la même façon, pick b + permute (ac) fournira du bac, bca … et continuera.

maintenant regarde le code

 function permutations(arr){ var len = arr.length, perms = [], rest, picked, restPerms, next; //for one or less item there is only one permutation if (len <= 1) return [arr]; for (var i=0; i 

Prenez votre temps pour comprendre cela. J'ai obtenu ce code ( pertumation en JavaScript )

Un autre en Python, ce n’est pas comme @ cdiggins, mais je pense que c’est plus facile à comprendre

 def permute(num): if len(num) == 2: # get the permutations of the last 2 numbers by swapping them yield num num[0], num[1] = num[1], num[0] yield num else: for i in range(0, len(num)): # fix the first number and get the permutations of the rest of numbers for perm in permute(num[0:i] + num[i+1:len(num)]): yield [num[i]] + perm for p in permute([1, 2, 3, 4]): print p 

Je pensais écrire un code pour obtenir les permutations d’un nombre entier quelconque de n’importe quelle taille, c’est-à-dire fournir un numéro 4567, nous obtenons toutes les permutations possibles jusqu’à 7654 … est le code écrit en “c”. Vous pouvez simplement le copier et l’exécuter sur tous les compilateurs open source. Mais certains défauts attendent d’être débogués. S’il vous plaît apprécier.

Code:

 #include  #include  #include  //PROTOTYPES int fact(int); //For finding the factorial void swap(int*,int*); //Swapping 2 given numbers void sort(int*,int); //Sorting the list from the specified path int imax(int*,int,int); //Finding the value of imax int jsmall(int*,int); //Gives position of element greater than ith but smaller than rest (ahead of imax) void perm(); //All the important tasks are done in this function int n; //Global variable for input OR number of digits void main() { int c=0; printf("Enter the number : "); scanf("%d",&c); perm(c); getch(); } void perm(int c){ int *p; //Pointer for allocating separate memory to every single entered digit like arrays int i, d; int sum=0; int j, k; long f; n = 0; while(c != 0) //this one is for calculating the number of digits in the entered number { sum = (sum * 10) + (c % 10); n++; //as i told at the start of loop c = c / 10; } f = fact(n); //It gives the factorial value of any number p = (int*) malloc(n*sizeof(int)); //Dynamically allocation of array of n elements for(i=0; sum != 0 ; i++) { *(p+i) = sum % 10; //Giving values in dynamic array like 1234....n separately sum = sum / 10; } sort(p,-1); //For sorting the dynamic array "p" for(c=0 ; c *(p+j)) { temp = *(p+i); *(p+i) = *(p+j); *(p+j) = temp; } } } } int imax(int *p, int i , int d) { while(ip[k]) { small = p[i]; j = i; } } return j; } 
 void permutate(char[] x, int i, int n){ x=x.clone(); if (i==n){ System.out.print(x); System.out.print(" "); counter++;} else { for (int j=i; j<=n;j++){ // System.out.print(temp); System.out.print(" "); //Debugger swap (x,i,j); // System.out.print(temp); System.out.print(" "+"i="+i+" j="+j+"\n");// Debugger permutate(x,i+1,n); // swap (temp,i,j); } } } void swap (char[] x, int a, int b){ char temp = x[a]; x[a]=x[b]; x[b]=temp; } 

J'ai créé celui-ci. basé sur des recherches trop permutées (qwe, 0, qwe.length-1); Juste pour que vous sachiez, vous pouvez le faire avec ou sans backtrack

Voici une méthode Ruby qui fonctionne comme #permutation.to_a qui pourrait être plus lisible pour les fous. C’est hella slow, mais aussi 5 lignes.

 def permute(ary) return [ary] if ary.size <= 1 ary.collect_concat.with_index do |e, i| rest = ary.dup.tap {|a| a.delete_at(i) } permute(rest).collect {|a| a.unshift(e) } end end 

J’ai écrit cette solution récursive dans ANSI C. Chaque exécution de la fonction Permutate fournit une permutation différente jusqu’à ce que tout soit terminé. Les variables globales peuvent également être utilisées pour les variables fact et count.

 #include  #define SIZE 4 void Rotate(int vec[], int size) { int i, j, first; first = vec[0]; for(j = 0, i = 1; i < size; i++, j++) { vec[j] = vec[i]; } vec[j] = first; } int Permutate(int *start, int size, int *count) { static int fact; if(size > 1) { if(Permutate(start + 1, size - 1, count)) { Rotate(start, size); } fact *= size; } else { (*count)++; fact = 1; } return !(*count % fact); } void Show(int vec[], int size) { int i; printf("%d", vec[0]); for(i = 1; i < size; i++) { printf(" %d", vec[i]); } putchar('\n'); } int main() { int vec[] = { 1, 2, 3, 4, 5, 6 }; /* Only the first SIZE items will be permutated */ int count = 0; do { Show(vec, SIZE); } while(!Permutate(vec, SIZE, &count)); putchar('\n'); Show(vec, SIZE); printf("\nCount: %d\n\n", count); return 0; } 

Version Java

 /** * @param uniqueList * @param permutationSize * @param permutation * @param only Only show the permutation of permutationSize, * else show all permutation of less than or equal to permutationSize. */ public static void my_permutationOf(List uniqueList, int permutationSize, List permutation, boolean only) { if (permutation == null) { assert 0 < permutationSize && permutationSize <= uniqueList.size(); permutation = new ArrayList<>(permutationSize); if (!only) { System.out.println(Arrays.toSsortingng(permutation.toArray())); } } for (int i : uniqueList) { if (permutation.contains(i)) { continue; } permutation.add(i); if (!only) { System.out.println(Arrays.toSsortingng(permutation.toArray())); } else if (permutation.size() == permutationSize) { System.out.println(Arrays.toSsortingng(permutation.toArray())); } if (permutation.size() < permutationSize) { my_permutationOf(uniqueList, permutationSize, permutation, only); } permutation.remove(permutation.size() - 1); } } 

Par exemple

 public static void main(Ssortingng[] args) throws Exception { my_permutationOf(new ArrayList() { { add(1); add(2); add(3); } }, 3, null, true); } 

sortie:

  [1, 2, 3] [1, 3, 2] [2, 1, 3] [2, 3, 1] [3, 1, 2] [3, 2, 1] 

en PHP

 $set=array('A','B','C','D'); function permutate($set) { $b=array(); foreach($set as $key=>$value) { if(count($set)==1) { $b[]=$set[$key]; } else { $subset=$set; unset($subset[$key]); $x=permutate($subset); foreach($x as $key1=>$value1) { $b[]=$value.' '.$value1; } } } return $b; } $x=permutate($set); var_export($x); 

entrer la description de l'image ici

 // C program to print all permutations with duplicates allowed #include  #include  /* Function to swap values at two pointers */ void swap(char *x, char *y) { char temp; temp = *x; *x = *y; *y = temp; } /* Function to print permutations of ssortingng This function takes three parameters: 1. Ssortingng 2. Starting index of the ssortingng 3. Ending index of the ssortingng. */ void permute(char *a, int l, int r) { int i; if (l == r) printf("%s\n", a); else { for (i = l; i <= r; i++) { swap((a+l), (a+i)); permute(a, l+1, r); swap((a+l), (a+i)); //backtrack } } } /* Driver program to test above functions */ int main() { char str[] = "ABC"; int n = strlen(str); permute(str, 0, n-1); return 0; } 

Référence: Geeksforgeeks.org

Voici le code en Python pour imprimer toutes les permutations possibles d’une liste:

 def next_perm(arr): # Find non-increasing suffix i = len(arr) - 1 while i > 0 and arr[i - 1] >= arr[i]: i -= 1 if i <= 0: return False # Find successor to pivot j = len(arr) - 1 while arr[j] <= arr[i - 1]: j -= 1 arr[i - 1], arr[j] = arr[j], arr[i - 1] # Reverse suffix arr[i : ] = arr[len(arr) - 1 : i - 1 : -1] print arr return True def all_perm(arr): a = next_perm(arr) while a: a = next_perm(arr) arr = raw_input() arr.split(' ') arr = map(int, arr) arr.sort() print arr all_perm(arr) 

J'ai utilisé un algorithme d'ordre lexicographique pour obtenir toutes les permutations possibles, mais un algorithme récursif est plus efficace. Vous pouvez trouver le code de l'algorithme récursif ici: permutations de récursion Python

 public class PermutationGenerator { private LinkedList> _permutationsList; public void FindPermutations(List list, int permutationLength) { _permutationsList = new LinkedList>(); foreach(var value in list) { CreatePermutations(value, permutationLength); } } private void CreatePermutations(int value, int permutationLength) { var node = _permutationsList.First; var last = _permutationsList.Last; while (node != null) { if (node.Value.Count < permutationLength) { GeneratePermutations(node.Value, value, permutationLength); } if (node == last) { break; } node = node.Next; } List permutation = new List(); permutation.Add(value); _permutationsList.AddLast(permutation); } private void GeneratePermutations(List permutation, int value, int permutationLength) { if (permutation.Count < permutationLength) { List copyOfInitialPermutation = new List(permutation); copyOfInitialPermutation.Add(value); _permutationsList.AddLast(copyOfInitialPermutation); List copyOfPermutation = new List(); copyOfPermutation.AddRange(copyOfInitialPermutation); int lastIndex = copyOfInitialPermutation.Count - 1; for (int i = lastIndex;i > 0;i--) { int temp = copyOfPermutation[i - 1]; copyOfPermutation[i - 1] = copyOfPermutation[i]; copyOfPermutation[i] = temp; List perm = new List(); perm.AddRange(copyOfPermutation); _permutationsList.AddLast(perm); } } } public void PrintPermutations(int permutationLength) { int count = _permutationsList.Where(perm => perm.Count() == permutationLength).Count(); Console.WriteLine("The number of permutations is " + count); } } 

À Scala

  def permutazione(n: List[Int]): List[List[Int]] = permutationeAcc(n, Nil) def permutationeAcc(n: List[Int], acc: List[Int]): List[List[Int]] = { var result: List[List[Int]] = Nil for (i ← n if (!(acc contains (i)))) if (acc.size == n.size-1) result = (i :: acc) :: result else result = result ::: permutationeAcc(n, i :: acc) result } 

c’est une version java pour la permutation

 public class Permutation { static void permute(Ssortingng str) { permute(str.toCharArray(), 0, str.length()); } static void permute(char [] str, int low, int high) { if (low == high) { System.out.println(str); return; } for (int i=low; i 

Voici une implémentation de ColdFusion (requirejs CF10 à cause de l’argument de fusion avec ArrayAppend ()):

 public array function permutateArray(arr){ if (not isArray(arguments.arr) ) { return ['The ARR argument passed to the permutateArray function is not of type array.']; } var len = arrayLen(arguments.arr); var perms = []; var rest = []; var restPerms = []; var rpLen = 0; var next = []; //for one or less item there is only one permutation if (len <= 1) { return arguments.arr; } for (var i=1; i <= len; i++) { // copy the original array so as not to change it and then remove the picked (current) element rest = arraySlice(arguments.arr, 1); arrayDeleteAt(rest, i); // recursively get the permutation of the rest of the elements restPerms = permutateArray(rest); rpLen = arrayLen(restPerms); // Now concat each permutation to the current (picked) array, and append the concatenated array to the end result for (var j=1; j <= rpLen; j++) { // for each array returned, we need to make a fresh copy of the picked(current) element array so as to not change the original array next = arraySlice(arguments.arr, i, 1); arrayAppend(next, restPerms[j], true); arrayAppend(perms, next); } } return perms; } 

Basé sur la solution js de KhanSharp ci-dessus.

Je le sais très très ancien et même hors sujet dans le stackoverflow d’aujourd’hui, mais je voulais quand même apporter une réponse JavaScript conviviale pour la simple raison qu’il s’exécute dans votre navigateur.

J’ai également ajouté le point d’arrêt de la directive de debugger afin que vous puissiez parcourir le code (chrome requirejs) pour voir comment fonctionne cet algorithme. Ouvrez votre console de développement en chrome ( F12 dans Windows ou CMD + OPTION + I sur Mac), puis cliquez sur “Exécuter l’extrait de code”. Cela implémente le même algorithme exact que @WhirlWind présenté dans sa réponse.

Votre navigateur doit suspendre l’exécution à la directive du debugger . Utilisez F8 pour continuer l’exécution du code.

Parcourez le code et voyez comment cela fonctionne!

 function permute(rest, prefix = []) { if (rest.length === 0) { return [prefix]; } return (rest .map((x, index) => { const oldRest = rest; const oldPrefix = prefix; // the `...` destructures the array into single values flattening it const newRest = [...rest.slice(0, index), ...rest.slice(index + 1)]; const newPrefix = [...prefix, x]; debugger; const result = permute(newRest, newPrefix); return result; }) // this step flattens the array of arrays returned by calling permute .reduce((flattened, arr) => [...flattened, ...arr], []) ); } console.log(permute([1, 2, 3])); 

Dans la solution Java suivante, nous profitons du fait que les chaînes de caractères sont immuables afin d’éviter le clonage du jeu de résultats à chaque itération.

L’entrée sera une chaîne, disons “abc”, et le résultat sera toutes les permutations possibles:

 abc acb bac bca cba cab 

Code:

 public static void permute(Ssortingng s) { permute(s, 0); } private static void permute(Ssortingng str, int left){ if(left == str.length()-1) { System.out.println(str); } else { for(int i = left; i < str.length(); i++) { String s = swap(str, left, i); permute(s, left+1); } } } private static String swap(String s, int left, int right) { if (left == right) return s; String result = s.substring(0, left); result += s.substring(right, right+1); result += s.substring(left+1, right); result += s.substring(left, left+1); result += s.substring(right+1); return result; } 

La même approche peut être appliquée aux tableaux (au lieu d'une chaîne):

 public static void main(Ssortingng[] args) { int[] abc = {1,2,3}; permute(abc, 0); } public static void permute(int[] arr, int index) { if (index == arr.length) { System.out.println(Arrays.toSsortingng(arr)); } else { for (int i = index; i < arr.length; i++) { int[] permutation = arr.clone(); permutation[index] = arr[i]; permutation[i] = arr[index]; permute(permutation, index + 1); } } } 

C’est ma solution sur Java:

 public class CombinatorialUtils { public static void main(Ssortingng[] args) { List alphabet = new ArrayList<>(); alphabet.add("1"); alphabet.add("2"); alphabet.add("3"); alphabet.add("4"); for (List ssortingngs : permutations(alphabet)) { System.out.println(ssortingngs); } System.out.println("-----------"); for (List ssortingngs : combinations(alphabet)) { System.out.println(ssortingngs); } } public static List> combinations(List alphabet) { List> permutations = permutations(alphabet); List> combinations = new ArrayList<>(permutations); for (int i = alphabet.size(); i > 0; i--) { final int n = i; combinations.addAll(permutations.stream().map(ssortingngs -> ssortingngs.subList(0, n)).distinct().collect(Collectors.toList())); } return combinations; } public static  List> permutations(List alphabet) { ArrayList> permutations = new ArrayList<>(); if (alphabet.size() == 1) { permutations.add(alphabet); return permutations; } else { List> subPerm = permutations(alphabet.subList(1, alphabet.size())); T addedElem = alphabet.get(0); for (int i = 0; i < alphabet.size(); i++) { for (List permutation : subPerm) { int index = i; permutations.add(new ArrayList(permutation) {{ add(index, addedElem); }}); } } } return permutations; } } 

Voici une solution récursive en PHP. Le post de WhirlWind décrit précisément la logique. Il convient de mentionner que la génération de toutes les permutations s’exécute en temps factoriel. Il peut donc être judicieux d’utiliser une approche itérative à la place.

 public function permute($sofar, $input){ for($i=0; $i < strlen($input); $i++){ $diff = strDiff($input,$input[$i]); $next = $sofar.$input[$i]; //next contains a permutation, save it $this->permute($next, $diff); } } 

La fonction strDiff prend deux chaînes, s1 et s2 , et renvoie une nouvelle chaîne avec tout dans s1 sans éléments dans s2 (les doublons sont importants). Donc, strDiff('finish','i') => 'fnish' (le second ‘i’ n’est pas supprimé).

Voici un algorithme en R, au cas où quelqu’un devrait éviter de charger des bibliothèques supplémentaires comme je le devais.

 permutations <- function(n){ if(n==1){ return(matrix(1)) } else { sp <- permutations(n-1) p <- nrow(sp) A <- matrix(nrow=n*p,ncol=n) for(i in 1:n){ A[(i-1)*p+1:p,] <- cbind(i,sp+(sp>=i)) } return(A) } } 

Exemple d’utilisation:

 > masortingx(letters[permutations(3)],ncol=3) [,1] [,2] [,3] [1,] "a" "b" "c" [2,] "a" "c" "b" [3,] "b" "a" "c" [4,] "b" "c" "a" [5,] "c" "a" "b" [6,] "c" "b" "a" 
 #!/usr/bin/env python import time def permutations(sequence): # print sequence unit = [1, 2, 1, 2, 1] if len(sequence) >= 4: for i in range(4, (len(sequence) + 1)): unit = ((unit + [i - 1]) * i)[:-1] # print unit for j in unit: temp = sequence[j] sequence[j] = sequence[0] sequence[0] = temp yield sequence else: print 'You can use PEN and PAPER' # s = [1,2,3,4,5,6,7,8,9,10] s = [x for x in 'PYTHON'] print s z = permutations(s) try: while True: # time.sleep(0.0001) print next(z) except StopIteration: print 'Done' 

 ['P', 'Y', 'T', 'H', 'O', 'N'] ['Y', 'P', 'T', 'H', 'O', 'N'] ['T', 'P', 'Y', 'H', 'O', 'N'] ['P', 'T', 'Y', 'H', 'O', 'N'] ['Y', 'T', 'P', 'H', 'O', 'N'] ['T', 'Y', 'P', 'H', 'O', 'N'] ['H', 'Y', 'P', 'T', 'O', 'N'] ['Y', 'H', 'P', 'T', 'O', 'N'] ['P', 'H', 'Y', 'T', 'O', 'N'] ['H', 'P', 'Y', 'T', 'O', 'N'] ['Y', 'P', 'H', 'T', 'O', 'N'] ['P', 'Y', 'H', 'T', 'O', 'N'] ['T', 'Y', 'H', 'P', 'O', 'N'] ['Y', 'T', 'H', 'P', 'O', 'N'] ['H', 'T', 'Y', 'P', 'O', 'N'] ['T', 'H', 'Y', 'P', 'O', 'N'] ['Y', 'H', 'T', 'P', 'O', 'N'] ['H', 'Y', 'T', 'P', 'O', 'N'] ['P', 'Y', 'T', 'H', 'O', 'N'] . . . ['Y', 'T', 'N', 'H', 'O', 'P'] ['N', 'T', 'Y', 'H', 'O', 'P'] ['T', 'N', 'Y', 'H', 'O', 'P'] ['Y', 'N', 'T', 'H', 'O', 'P'] ['N', 'Y', 'T', 'H', 'O', 'P'] 

Bourne shell solution – en quatre lignes au total (sans test pour aucun cas de param):

 test $# -eq 1 && echo "$1" && exit for i in $*; do $0 `echo "$*" | sed -e "s/$i//"` | sed -e "s/^/$i /" done 

Ceci est un code récursif pour java, l’idée est d’avoir un préfixe qui ajoute le rest des caractères:

 public static void permutation(Ssortingng str) { permutation("", str); } private static void permutation(Ssortingng prefix, Ssortingng str) { int n = str.length(); if (n == 0) System.out.println(prefix); else { for (int i = 0; i < n; i++) permutation(prefix + str.charAt(i), str); } } 

Exemple:

Input = "ABC"; Sortie:

ABC ACB BAC BCA CAB CBA

Juste pour être complet, C ++

 #include  #include  #include  std::ssortingng theSeq = "abc"; do { std::cout << theSeq << endl; } while (std::next_permutation(theSeq.begin(), theSeq.end())); 

...

 abc acb bac bca cab cba 

Vous ne pouvez pas vraiment parler de résoudre un problème de permultation en récursivité sans afficher une implémentation dans un langage (dialectal de) qui a été à l’origine de l’idée . Donc, par souci d’exhaustivité, voici l’une des façons de procéder dans le cadre du programme.

 (define (permof wd) (cond ((null? wd) '()) ((null? (cdr wd)) (list wd)) (else (let splice ([l '()] [m (car wd)] [r (cdr wd)]) (append (map (lambda (x) (cons mx)) (permof (append lr))) (if (null? r) '() (splice (cons ml) (car r) (cdr r)))))))) 

appelant (permof (list "foo" "bar" "baz")) nous aurons:

 '(("foo" "bar" "baz") ("foo" "baz" "bar") ("bar" "foo" "baz") ("bar" "baz" "foo") ("baz" "bar" "foo") ("baz" "foo" "bar")) 

Je ne vais pas entrer dans les détails de l’algorithme, car il a été suffisamment expliqué dans d’autres articles. L’idée est la même.

Cependant, les problèmes récursifs ont tendance à être beaucoup plus difficiles à modéliser et à penser dans un support destructeur tel que Python, C et Java, tandis que dans Lisp ou ML, il peut être exprimé de manière concise.