Ho dovuto risolvere questo esatto problema qualche anno fa. Non ero in grado di venire con la mia soluzione, ma invece sono imbattuto in questo meraviglioso pezzo di codice che comporta l'uso intelligente e giudizioso di map
insieme con la ricorsione:
#!/usr/bin/perl
print "permute:\n";
print "[", join(", ", @$_), "]\n" for permute([1,2,3], [4,5,6], [7,8,9]);
sub permute {
my $last = pop @_;
unless(@_) {
return map([$_], @$last);
}
return map {
my $left = $_;
map([@$left, $_], @$last)
}
permute(@_);
}
Sì, questo sembra folle, ma mi consenta spiegare! La funzione verrà inoltrata fino a quando @_
è vuoto, a quel punto restituisce ([1], [2], [3])
(un elenco di tre arrayrefs) al livello precedente di ricorsione. A questo livello, $last
è un riferimento a un array che contiene [4, 5, 6]
.
Il corpo della mappa esterno viene quindi eseguito tre volte con $_
insieme a [1]
, poi [2]
e infine [3]
. La mappa interna viene quindi eseguita su (4, 5, 6)
per ogni iterazione della mappa esterna e restituisce ([1, 4], [1, 5], [1, 6])
, ([2, 4], [2, 5], [2, 6])
e infine ([3, 4], [3, 5], [3, 6])
.
La seconda chiamata ricorsiva restituisce ([1, 4], [1, 5], [1, 6], [2, 4], [2, 5], [2, 6], [3, 4], [3, 5], [3, 6])
.
Poi, che gira quel risultato contro [7,8,9]
, che vi dà [1, 4, 7], [1, 4, 8], [1, 4, 9], [1, 5, 7], [1, 5, 8], [1, 5, 9], [1, 6, 7], [1, 6, 8], [1, 6, 9], [2, 4, 7], [2, 4, 8], [2, 4, 9], [2, 5, 7], [2, 5, 8], [2, 5, 9], [2, 6, 7], [2, 6, 8], [2, 6, 9], [3, 4, 7], [3, 4, 8], [3, 4, 9], [3, 5, 7], [3, 5, 8], [3, 5, 9], [3, 6, 7], [3, 6, 8], [3, 6, 9]
Mi ricordo di postare una domanda sul perlmonks.org chiedere a qualcuno di spiegare questo a me.
È possibile adattare facilmente questa soluzione al proprio problema.
Questo non è permutazione - permutazione è ordinamenti di un dato insieme (ad esempio {a, b, c} -> (a, b, c), (a, c, b), (b, a, c), ...). – Cascabel
oh scusa. Non lo sapevo È combinazioni ?? – user295033
In realtà, ho appena notato che si tratta di un duplicato: vedere http://stackoverflow.com/questions/1256036/in-perl-how-can-i-iterate-over-the-cartesian-product-of-multiple-sets –