Se avete installato Perl 5.8.0 o successivo, o avete installato
Scalar-List-Utils 1.03 o successivo, potete scrivere:
use List::Util 'shuffle';
@mescolato = shuffle(@lista);
In caso contrario, potete utilizzare l'argoritmo di mescolamento
Fisher-Yates:
sub mescola_fisher_yates {
my $mazzo = shift; # $mazzo e` un riferimento ad un array
my $i = @$mazzo;
while (--$i) {
my $j = int rand ($i+1);
@$mazzo[$i,$j] = @$mazzo[$j,$i];
}
}
# mescola la mia collezione di mpeg
#
my @mpeg = <audio/*/*.mp3>;
mescola_fisher_yates( \@mpeg ); # mescola @mpeg "sul posto"
print @mpeg;
Notate che l'implementazione sopra indicata mescola un array "sul posto",
a differenza di List::Util::shuffle() che prende una lista e ne restituisce una
nuova mescolata.
Avete probabilmente visto algoritmi di mescolamento che funzionano
utilizzando splice, prendendo a caso un elemento da scambiare con
quello corrente.
srand;
@nuovo = ();
@vecchio = 1 .. 10; # solo una dimostrazione
while (@vecchio) {
push(@nuovo, splice(@vecchio, rand @nuovo, 1));
}
Questa è una cattiva pratica, poiché splice è
già O(N) e, poiché lo eseguite N volte, avete appena
inventato un algoritmo quadratico; il che significa O(N**2). Esso non
scala bene, anche se Perl è così efficiente che
probabilmente non noterete la cosa finché non avrete array
piuttosto grandi.
|