3

これはおそらく広く議論されていますが、まだ適切な答えを見つけることができません. これが私の問題です。現在の範囲に数値を入れたいのですが、数値はランダムです。使わない

Random rand = new Random(); 
rand.Next(0,100);

番号は fromGetHashCode(),であり、範囲内に配置する必要があります *[0, someArray.Length);

私は試した :

int a = 12345;
int currentIndex = a.GetHashCode();
currentIndex % someArray.Length + someArrayLength

しかし、うまくいきません。どんな助けにも感謝します。

4

3 に答える 3

4

私は行き(hash & 0x7FFFFFFF) % modulusます。マスキングにより、入力が正であることが保証され、剰余演算子が%それをターゲット範囲にマップします。

代替手段は次のとおりです。

result = hash % modulus;
if(result < 0)
    result += modulus;

result = ((hash % modulus) + modulus) % modulus

残念ながらうまくいかないのは

result = Math.Abs(hash) % modulus

Math.Abs(int.MinValue)でありint.MinValue、したがって負であるからです。このアプローチを修正するには、次のようにキャストできlongます。

result = (int)(Math.Abs((long)hash)) % modulus)

これらの方法はすべて、入力値の数がモジュラスの整数倍でない限り、同じ確率で各出力値にマッピングできないため、一部の入力範囲とモジュラス値にわずかな偏りをもたらします。状況によってはこれが問題になることもありますが、ハッシュテーブルでは問題ありません。

主にパフォーマンスを気にする場合は、マスキング ソリューションが望ましい&です%

于 2013-06-14T18:22:58.853 に答える
1

負の値を処理する適切な方法は、二重係数を使用することです。

int currentIndex = ((a.GetHashCode() % someArray.Length) + someArray.Length) % someArray.Length;

ミックスにいくつかの変数を導入します。

int len = someArray.Length;
int currentIndex = ((a.GetHashCode() % len) + len) % len;

これにより、最初に -len から (len -1) までの値の範囲が作成されるため、それに len を追加すると、0 から len*2-1 までの範囲になります。 0 から len-1 の範囲の値で、これが必要です。

このメソッドは、 のすべての有効な値を処理します。a.GetHashCode()特殊なハンドルint.MinValueまたはは必要ありませんint.MaxValue

このメソッドは、入力に 1 を追加すると (a.GetHashCode()この場合は重要ではない可能性があります)、出力に 1 を追加することになることに注意してください (最後に到達すると 0 にラップします)。 . またはビットごとの操作を使用して正の値を保証する方法はMath.Abs、負の数の場合とは異なります。それはあなたが望むものに依存します。

于 2013-06-14T18:21:23.807 に答える