1

Bob Jenkins ハッシュ関数の大文字と小文字を区別しないバリアントはありますか?

Generics.Defaults.BobJenkinsHash

高速ハッシュ関数を提供します。残念ながら、大文字と小文字を区別しない比較関数と組み合わせて使用​​ することはできません

TCustomStringComparer = class (TEqualityComparer <String>)
  function Equals(const Left, Right: String): Boolean; override;
  function GetHashCode(const Value: String): Integer; override;
end;
function TCustomStringComparer.Equals (const Left, Right : String) : Boolean;
begin
  Result := CompareText (Left, Right) = 0;
end;
function TCustomStringComparer.GetHashCode (const Value : String) : Integer;
begin
  Result := Generics.Defaults.BobJenkinsHash (Value [1], Length (Value) * SizeOf (Char), 0);
end;

これは、TDictionary が最初にハッシュ コードを比較し、次に提供された比較演算子を使用して等価性をチェックするためです。

もちろん、UpperCase をGetHashCode関数内で使用することもできますが、ハッシュ関数自体を何らかの方法で変更できれば、より高速になるのではないかと考えました。

4

4 に答える 4

3

IMO 質問全体が間違っています。ハッシュ関数に関するウィキペディアの記事を引用するには:

ハッシュ関数は、大量の、場合によっては可変サイズのデータ​​を小さなデータ (通常は配列のインデックスとして機能する単一の整数) に変換する、明確に定義された手順または数学関数です。

「データの量」に注意してください。タイプが指定されていません。実際、Bob Jenkins ハッシュ関数には、const Dataハッシュされるデータを指す型指定されていないパラメーターがあります。入力データは必ずしも一連の文字であるとは限らないため、「大文字と小文字を区別しない」ハッシュ値を計算する方法はありません。また、それが一連​​の文字であったとしても、大文字または小文字は文字セットとエンコーディングに依存します。そのため、ASCII 文字列、UTF-8 でエンコードされた文字列、UTF-16 LE でエンコードされた文字列など、さまざまなハッシュ関数が必要になります (おわかりでしょう)。

于 2009-10-30T12:30:50.967 に答える
3

少し速くなりますが、保守性が大幅に低下します。このタイプのマイクロ最適化に正当な理由があることはめったにありません。あなたが提案したようにハッシュする前に、文字列を小文字または大文字に変換するだけです。

「私たちはわずかな効率を忘れるべきです。たとえば、約 97% の確率で: 時期尚早の最適化はすべての悪の根源です。しかし、その重要な 3% の機会を逃してはなりません。優れたプログラマーは、そのようなことで自己満足に陥ることはありません。論理的に考えると、彼は重要なコードを注意深く見るのが賢明ですが、そのコードが特定された後でのみです」 - ドナルド・クヌース

于 2009-10-30T12:03:50.870 に答える