2

GetHashCode() メソッドが文字列値に対してどのように機能するかを理解するのを手伝ってくれる人はいますか?

私が見つけたMSDNから:

2 つの文字列オブジェクトが等しい場合、GetHashCode メソッドは同じ値を返します。ただし、一意の文字列値ごとに一意のハッシュ コード値はありません。異なる文字列が同じハッシュ コードを返す場合があります。

したがって、異なる文字列が同じハッシュ コードを返す可能性があります。ハッシュ コードは文字列に対して一意ではありません。プログラムのコアにバグが発生する可能性はありますか?

4

5 に答える 5

3

一致するハッシュ コードが一致する文字列を意味すると仮定すると、バグが発生する可能性があります。通常、ハッシュ コードを使用して文字列をバケットに並べ替え、すばやく検索および選択できるようにします。2 つの文字列のハッシュ コードが一致することを検出した場合は、通常、文字列自体が等しいかどうかを比較します。

それがあなたの質問に答えないなら、私は質問を理解していません。

于 2012-09-17T18:23:52.657 に答える
3

アルゴリズムが各文字列に依存して一意のハッシュ値を持つ場合、これはバグにつながる可能性があります。

たとえば、ハッシュ マップ (.NET の辞書) は衝突 (つまり、同じハッシュを持つ 2 つのオブジェクトが等しくない) で失敗する可能性があります。正確な実装によっては、衝突を処理する場合でも失敗します。その場合の失敗の意味: 新しいオブジェクトをマップに追加し、新しいオブジェクトと同じハッシュ値を持つオブジェクトがマップに既に存在する場合、新しいオブジェクトは単に追加されるのではなく、古いオブジェクトをオーバーライドします。私の知る限り、.NET の Dictionary クラスは衝突を処理できます。

より具体的なアドバイスが必要な場合は、より具体的な質問をする必要があります: 何をアーカイブしようとしているのか、どのようにアーカイブする予定があるのか​​など。

補足として、ハッシュ値のサイズは制限されているため、通常、文字列のハッシュ値は一意ではありませんが、文字列の長さは制限されていません。次のように考えてみてください: ハッシュ関数が MD5 (.Net のデフォルトではありません) で、文字列が両方とも 16 進文字 (0-9A-Z) で構成され、文字列の長さが 200 文字であるとします。文字列の可能な値は 200^16 ですが、ハッシュ値の可能な値は 32^16 のみです。

于 2012-09-17T18:24:35.890 に答える
2

ドキュメントは、実際にメソッドが行う保証についてかなり正確です。ハッシュ コードは次の 2 つのルールに従います (a == bを参照しa.Equals(b)、読みやすくするために#aを参照しa.GetHashCode()ます)。

  • ならa == b_#a == #b
  • なら#a != #b_a != b

これは、 と一致するハッシュとは同等ではないことに注意してください。Equalsそれ以上に依存している場合は、明らかにコードにバグがあります。GetHashCodeオブジェクトから数値への迅速なマッピングができるように、オブジェクトを辞書のキーとして使用することを目的としていますが、元に戻す必要はありません。文字列を見ると、考えられる文字列の数が考えられるハッシュ コードの数をすぐに上回っていることが簡単にわかります。そのため、その質問には自分で答えることができたはずです。すでに 2 文字強で2 32の可能な文字列を超えています。

于 2012-09-17T18:31:13.947 に答える
2

ハッシュコードは、ハッシュ コレクション内のオブジェクトの検索を高速化するために使用されます。内部的には、オブジェクトを多くのバケットに格納します。保持されているオブジェクトは、ハッシュコードに基づいてバケットに分割されます。たとえば、あなたが呼び出すとき

var value = Dictionary["someKey"]

すべての内部バケットを検索する代わりに、辞書はそのキーの下に値を含む必要があるバケットに直接移動します。そして辞書検索はそのバケットでのみ行われます。

たぶん、これは正確に実装されている方法ではないかもしれませんが、多かれ少なかれそうあるべきです。したがって、この場合、辞書内の異なるキーが同じハッシュコードを持っていても問題ありません。これは、そのキーの下の値が同じバケットに入ることを意味するだけです。

于 2012-09-17T18:29:17.317 に答える
2

したがって、異なる文字列が同じハッシュ コードを返す可能性があります。ハッシュコードは文字列に対して一意ではありません。プログラムのコアにバグが発生する可能性はありますか?

ハッシュ値が意図したとおりに使用されていれば、バグにつながることはありません。によって返されるハッシュは、GetHashCode()一意のハッシュを提供することを意図したものではありません。可能なハッシュ コードは約 40 億個しかないため (メソッドが を返すためInt32)、可能な文字列は無限にあるため、これは不可能です。

ハッシュは、衝突を回避するためではなく、少数のコレクションを提供することを目的としています。そのため、ハッシュが値に基づく一意の表現であると想定してはなりません。唯一の保証は、2 つの異なる文字列に対する 2 つの異なるハッシュ コードは、文字列が等しくないことを意味するということです。これは、2 つの等しい値は常に同じハッシュを生成する必要があるためです。ただし、2 つのハッシュ コードが等しいからといって、必ずしも 2 つの文字列値が等しいとは限りません。

于 2012-09-17T18:28:51.323 に答える