array
インプレーススワッピングを使用して、O(n)でシャッフルすることは難しくありません。
list
O(n)を使ってOCamlでそれを行う方法は?
要件:
アレイなしまたはインプレース使用
これを面接の質問と考えてください
array
インプレーススワッピングを使用して、O(n)でシャッフルすることは難しくありません。
list
O(n)を使ってOCamlでそれを行う方法は?
要件:
アレイなしまたはインプレース使用
これを面接の質問と考えてください
リストは不変であり、不変のデータを処理するために支払う対数の代償がしばしばあります。このコストを支払う意思がある場合は、明らかなn log nアプローチがあります。各リスト要素にランダムな値をタグ付けし、ランダムな値に基づいて並べ替え、ランダムな値を削除します。これは、本番コードでリストをシャッフルする方法です。
これが私が販売しているiOSアプリのシャッフルコードです。
let shuffle d =
let nd = List.map (fun c -> (Random.bits (), c)) d in
let sond = List.sort compare nd in
List.map snd sond
カードのリフルシャッフルを模倣することができます。
カードのデッキのリフルシャッフルは、次のことを意味します。
実際には、逆順列を実行する方が簡単です。
「パーシ・ダイアコニスによるリフルシャッフリングの分析からの数学的発展、2002年」によれば、k = 3/2 log_2(n)+cを選択します。実際、均一性と結果の間の合計変動距離は指数関数的に0に低下します。つまり、cをインクリメントするたびに約半分になります。c=10を選択できます。
スペースO(1)(Lを破壊した場合)、時間O(n log n)。ただし、ランダムジェネレーターへのO(n log n)呼び出しがありますが、Jeffrey ScofieldのソリューションにはO(n)ランダムビットのみが必要ですが、Θ(n)スペースが必要です。