数値を割り当てるモジュラスの使用例
各文字列を 0 ~ 5 または 1 ~ 6 の数値に制限し、変化するデータ セットや不完全なデータ セットを使用する必要がある場合、目的の最終結果を達成することは不可能です。6 つの文字列を取り、それらを crc し、モジュラス 6 を実行して結果を表示するとします。入力:
Array
(
[0] => string1
[1] => string2
[2] => string3
[3] => string4
[4] => string5
[5] => string6
)
(crc32
を使用してsprintf('%u', crc32('string'))
:
Array
(
[0] => 742935113
[1] => 3040943091
[2] => 3259378533
[3] => 1545780934
[4] => 723881552
[5] => 2989285354
)
の結果crc32 % 6
:
Array
(
[0] => 5
[1] => 1
[2] => 1
[3] => 4
[4] => 2
[5] => 1
)
ご覧のとおり、「string2」、「string3」、および「string6」はすべてバケットとの衝突があり、その結果、「1」が割り当てられました。衝突検出では+1
、空のバケットを見つけるまでの単純な方法が使用されます。この例。したがって、bucket
配列は次のようになります。
Array
(
[0] => string6
[1] => string2
[2] => string3
[3] => string5
[4] => string4
[5] => string1
)
次回、元の入力から取り除くと[1] => string2
、6 つの結果の配列は次のようになります。
Array
(
[0] =>
[1] => string3
[2] => string5
[3] => string6
[4] => string4
[5] => string1
)
これは、少数のキーでデータセットが不完全な場合に何が起こるかを示しています。
問題は、load
. 6 つの可能なテキストがあり、6 つしかないため、これの負荷は 100%buckets
です。ハッシュ テーブルを作成するときは、負荷を 0 に近づけたいと考えています。また、6 つのエントリで負荷が 50% の場合、12 個のバケットが利用可能である必要があります。
覚えておいてください
PHP でa を使用している間modulus
は、最大整数サイズにも注意する必要があります。これは、モジュラス操作に使用される値が整数にキャストされるためです。
モジュラスのオペランドは、処理前に (小数部分を取り除くことによって) 整数に変換されます。
システムに応じて、32 ビットまたは 64 ビットのいずれかになります。署名されていない crc32 は 32 ビット システムの最大キャップを超え、int キャップを返します。これは、数値の半分が (統計的に) 同じバケットで終わることを意味します。 '。
私たちは何ができる?
問題は、選択できる数の範囲です。異なる文字列番号を割り当てるための目的のアプリケーションに応じてcrc32
、結果からの衝突の数が小さなデータセットの場合は最小限になるため、実数を使用できます - ただし、入力テキスト (または説明されているように小さな範囲)、割り当てられた数値を各実行で一定に保ちながら、部分的なデータセットを許可するソリューションはありません。スクリプトが実行されるたびに入力文字列がランダムな順序で並べられているため、実行ごとに異なる時間に処理されると、衝突によって順序が逆になる可能性があるため、結果の整数を毎回同じに保つ方法はまったくありません。
目的がファイルにラベルを付けること、または何かにアクセスする手段である場合は、より大きなハッシュを使用し、mod
サイズに合わせないようにしてください。