配列をシャッフルしたい(ランダムな順列) - Perl

配列(リスト)を順不同に並べ替えたい。 トランプで言う「シャッフル」、アルゴリズム的な用語を使うと「ランダムな順列」に該当する。

次のようなプログラムを記述すれば良い。

サンプル

;#
;#配列をシャッフルする
;#

#-- シャッフルする値を準備 --#
@array = (0,1,2,3,4,5);

#-- シャッフル --#
shuffleArray(\@array);
print join("\n", @array);


#-----------------------------------#
#配列をシャッフル
#-----------------------------------#
sub shuffleArray{
 my $array = shift;
 my $len = scalar(@$array);

 for(my $i=$len-1 ; $i>=0; --$i){
  my $j = int( rand($i+1) );
  next if($i==$j);

  @$array[$i, $j] = @$array[$j, $i];

 }
}

実行結果

3
5
2
1
4
0

やり方は非常にシンプルだ。 配列を最後から最初にもどるように見て行く。その際に適当に選んだ要素とスワップ(入れ替え)をしていくという寸法である。このアルゴリズムは「Fisher-Yatesシャッフル」と呼ばれ、広く使用されている。

shuffleArray関数では、渡された配列(のリファレンス)を直接参照して書き換える点に注意されたい。

参考