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