Vedi perlfaq4: "How do I permute N elements of a list?"
Utilizzare la Lista :: modulo Permutor su CPAN. Se la lista è in realtà una matrice, prova il modulo Algorithm :: Permute (anche su CPAN). E 'scritto in codice XS ed è molto efficiente:
use Algorithm::Permute;
my @array = 'a'..'d';
my $p_iterator = Algorithm::Permute->new (\@array);
while (my @perm = $p_iterator->next) {
print "next permutation: (@perm)\n";
}
Per l'esecuzione ancora più veloce, si potrebbe fare:
use Algorithm::Permute;
my @array = 'a'..'d';
Algorithm::Permute::permute {
print "next permutation: (@array)\n";
} @array;
Ecco un piccolo programma che genera tutte le permutazioni di tutte le parole su ogni riga di input . L'algoritmo incarnata nella funzione permute() è discusso nel Volume 4 (ancora inedito) di di Knuth The Art of Computer Programming e funziona su qualsiasi elenco:
#!/usr/bin/perl -n
# Fischer-Krause ordered permutation generator
sub permute (&@) {
my $code = shift;
my @idx = 0..$#_;
while ($code->(@_[@idx])) {
my $p = $#idx;
--$p while $idx[$p-1] > $idx[$p];
my $q = $p or return;
push @idx, reverse splice @idx, $p;
++$q while $idx[$p-1] > $idx[$q];
@idx[$p-1,$q][email protected][$q,$p-1];
}
}
permute { print "@_\n" } split;
L'algoritmo :: modulo Loops offre anche la NextPermute e NextPermuteNum funziona in modo efficiente per trovare tutte le permutazioni univoche di un array, anche se contiene valori duplicati, modificandolo sul posto: se i suoi elementi sono in ordine inverso, la matrice viene invertita, rendendola ordinata e restituisce false; altrimenti viene restituita la prossima permutazione.
NextPermute utilizza ordine d'archi e NextPermuteNum ordine numerico, in modo da poter enumerare tutte le permutazioni di 0..9 come questo:
use Algorithm::Loops qw(NextPermuteNum);
my @list= 0..9;
do { print "@list\n" } while NextPermuteNum @list;
fonte
2009-03-12 09:47:26
L'articolo è una lettura interessante. Grazie! –