ランダム順列
id:succeed:20060127#1138378979
2番目のやつは間違ってるような。
ソートアルゴリズムが安定だと小さい数が先に出てくる確率が高いし、
そうでなくてもランダムではない。
例えば n=2 で、ソートアルゴリズムが安定で、
rand() の返り値が k 通りあるとすると
(k+1)/(2k) の確率で先に 1 が出る。
普通は k が大きすぎて分からないけど
my $n = 2; my $m = 1; my @array = map {[$_, int(rand(2))]} (1..$n); @array = sort {$a->[1] <=> $b->[1]} @array; foreach(0..$m-1){ print $array[$_]->[0], "\n"; }
とかにして100回ほど実験すると 3/4 くらいの割合で 1 が出る。
関数型っぽく実装するなら木構造を使うのが無難かと。
以下 ocaml
module M = Map.Make (struct type t = int let compare x y = x - y end) let find x env = try M.find x env with Not_found -> x let rec iter n env acc = if n <= 0 then acc else let r = Random.int n + 1 in iter (n-1) (M.add r (find n env) env) (find r env :: acc) let random_list n = iter n M.empty []
アルゴリズムは3番目とほぼ同じで時間はO(n*log n)。