Récursive prend toujours un certain effort mental à maintenir. Et pour les grands nombres, factorielle est facilement énorme et de dépassement de pile sera facilement être un problème.
Pour les petits groupes (3 ou 4, ce qui est le plus souvent rencontrés), plusieurs boucles sont assez simple et direct. Il est regrettable réponses avec des boucles avais pas voté.
Commençons par énumération (plutôt que de permutation). Il suffit de lire le code du 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 souvent rencontré de permutation, mais si la permutation est nécessaire, il suffit d'ajouter 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 de méthode générale potentiellement pour les grandes listes, on peut utiliser radix méthode. 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
Radix incrément est essentiellement le nombre de comptage (dans la base de nombre d'éléments de liste).
Maintenant, si vous avez besoin d'permutaion, il suffit d'ajouter les contrôles à 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 une préoccupation 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, maintenant ce code est logiquement plus complexe, je vais partir pour le lecteur de l'exercice.