質問
説明
permutationIndex
セクションで説明した 52 枚のカードだけでも膨大な数になります。のいずれかの数値であり、格納するには 29 バイトが必要です。52!
したがって、巨大な範囲のを計算し、最小限のコストでインデックスを保存する簡単な方法がわかりません。または、計算することもできます。
permutationIndex
この質問の解決策は、次の 3 つのアルゴリズムになると考えています。メソッド
permutationIndex
を実装Dealing
するための正しい計算アルゴリズムメソッド
permutationIndex
を実装Collect
するための正しい計算アルゴリズム最小限のコストで格納 (または計算) するアルゴリズム
permutationIndex
説明
私は元々、順列を使用してから までの範囲の整数ハンドル ジェネレーターを実装しようとしています。
int.MinVale
int.MaxValue
その範囲は非常に大きいため、ハッシュセットや配列などのカードのデッキを実際に格納せず、ランダム(初期を除く) を必要としない 52 枚のカードを持つクラスを実装することから始めます。
Dealer
与えられた範囲の序数を使用して、完全順列のいずれかのすべてのシーケンスにインデックスがあると見なし、名前を付けました
permutationIndex
。私はインデックスを使用してそれがどの順列であるかを覚えており、実際にはシーケンスを保存していません。シーケンスは、カードのデッキの可能な順序の 1 つです。そして、私が考えたことを示すために、アニメーション グラフィックスでのエミュレーションの例を示します。
permutationIndex
カードを配るたびにand (配られたカードの数) を変更し、dealt
どのカードが配られ、どのカードがまだ手元にあるかを知っています。配られたカードの裏を集めるとカード番号がわかるので、一番上に置くと次回配るカードにもなります。アニメーションでcolleted
は、 はカード番号です。
詳細については、次のとおりです。
コードの説明
Dealer
3 つのみの概念的なサンプルクラスは次のとおりです。コードはc#で書かれており、言語に依存しないソリューションも検討しています。サンプルコードの説明を次に示します。
メソッドで、配られたカードの枚数
Dealing()
を取得します。常に右端の番号 (配列に関連する) を返し、次に変更することによって、左端の番号 (次の使用可能な番号など) を右端の位置にロールします。permutationIndex
Collect(int)
配られたカードを集めて山札に戻す方法です。ディーラーに返されたカードの枚数permutationIndex
によっても変わります。整数
dealt
は、配ったカードの枚数を示します。一番左から に格納されている数までdealt
配られたカードです。でpermutationIndex
、カードの並びがわかります。サンプル コードの
int[,]
配列は、順列を想像しやすくするために使用されていません。switchステートメントは、を計算するアルゴリズムで実装されていると見なされますpermutationIndex
。これは、高速順列 -> 数値 -> 順列マッピング アルゴリズム
permutationIndex
のこの回答で説明されているものと同じです。
サンプルコード
public static class Dealer { public static void Collect(int number) { if(1>dealt) throw new IndexOutOfRangeException(); switch(permutationIndex) { case 5: case 0: switch(number) { case 3: break; case 2: permutationIndex=1; break; case 1: permutationIndex=4; break; } break; case 4: case 3: switch(number) { case 3: permutationIndex=5; break; case 2: permutationIndex=2; break; case 1: break; } break; case 2: case 1: switch(number) { case 3: permutationIndex=0; break; case 2: break; case 1: permutationIndex=3; break; } break; } --dealt; } public static int Dealing() { if(dealt>2) throw new IndexOutOfRangeException(); var number=0; switch(permutationIndex) { case 5: permutationIndex=3; number=3; break; case 4: permutationIndex=0; number=1; break; case 3: permutationIndex=1; number=1; break; case 2: permutationIndex=4; number=2; break; case 1: permutationIndex=5; number=2; break; case 0: permutationIndex=2; number=3; break; } ++dealt; return number; } static int[,] sample= new[,] { { 1, 2, 3 }, // 0 { 1, 3, 2 }, // 1 { 3, 1, 2 }, // 2 { 3, 2, 1 }, // 3 { 2, 3, 1 }, // 4 { 2, 1, 3 }, // 5 }; static int permutationIndex; static int dealt; }