web-dev-qa-db-ja.com

ハッシュ:内部的にはどのように機能しますか?

これは非常に曖昧な質問のように聞こえますが、そうではありません。 ハッシュ関数 wikiの説明を読み終えましたが、理解するのはあまり役に立ちません。

ハッシングのようなやや複雑なトピックの簡単な答えを探しています。私の質問は次のとおりです。

  1. ハッシュとはどういう意味ですか?内部的にはどのように機能しますか?
  2. どのアルゴリズムに従うのですか?
  3. HashMapHashTableHashListの違いは何ですか?
  4. 「一定時間の複雑さ」とはどういう意味ですか?また、ハッシュの異なる実装が一定時間の操作を提供するのはなぜですか?
  5. 最後に、ほとんどのインタビューの質問HashおよびLinkedListが尋ねられるのはなぜですか、インタビュー対象者の知識をテストすることから特定のロジックがありますか?

私の質問リストが大きいことは知っていますが、トピックを本当に理解したいので、これらの質問に対する明確な答えを得ることができれば本当に感謝しています。

49
Rachel
  1. ここ はハッシュについての良い説明です。たとえば、文字列「Rachel」を保存するには、その文字列にハッシュ関数を適用してメモリの場所を取得します。 myHashFunction(key: "Rachel" value: "Rachel") --> 10。関数は、入力 "Rachel"に対して10を返すことがあります。サイズ100の配列があると仮定すると、インデックス10に "Rachel"を格納します。その要素を取得する場合は、GetmyHashFunction("Rachel")を呼び出すだけです10.この例では、キーは「Rachel」で値は「Rachel」ですが、誕生日やオブジェクトなど、そのキーに別の値を使用できます。ハッシュ関数は、2つの異なる入力に対して同じメモリ位置を返す場合があります。この場合、独自のハッシュテーブルを実装している場合、リンクリストまたは他の手法を使用してこれを処理する必要があります。

  2. ここ は、使用される一般的なハッシュ関数です。優れたハッシュ関数はそれを満たします。各キーは、他のキーがハッシュされた場所とは無関係に、n個のメモリスロットのいずれかにハッシュされる可能性が等しくなります。方法の1つは、除算方法と呼ばれます。キーのkをnで割った余りを取得して、キーkをnスロットの1つにマッピングします。 h(k) = k mod n。たとえば、配列サイズが_n = 100_で、キーが整数_k = 15_の場合、h(k) = 10です。

  3. Hashtableは同期されますが、Hashmapは同期されません。 Hashmapでは、null値をキーとして使用できますが、Hashtableでは使用できません。

  4. ハッシュテーブルの目的は、要素を追加および取得する際にO(c)一定の時間の複雑さを持たせることです。最後の要素を取得する場合は、サイズNのリンクリストで複雑さがO(N)になるように、取得するまですべてのリストをトラバースします。ハッシュテーブルでは、要素を取得する場合はキーを渡すだけで、ハッシュ関数は目的の要素を返します。実装された時間は一定時間になりますO(c)これは、ハッシュテーブルに保存されているすべての要素を走査する必要がないことを意味します。要素は「即座に」取得されます。

  5. プログラマー/開発者のコ​​ンピューター科学者は、データ構造と複雑さについて知っておく必要があります=)

28
Enrique
  1. ハッシュとは、値を表す(できれば)一意の番号を生成することです。
  2. 異なるタイプの値(IntegerStringなど)は、異なるアルゴリズムを使用してハッシュコードを計算します。
  3. HashMapとHashTableはmaps;です。これらは一意のキーのコレクションであり、それぞれが値に関連付けられています。
    JavaにはHashListクラスがありません。ハッシュセット 一意の値のセットです。
  4. ハッシュテーブルからアイテムを取得することは、テーブルのサイズに関して一定時間です。
    ハッシュの計算は、ハッシュされる値に関して必ずしも一定時間ではありません。
    たとえば、文字列のハッシュの計算には、文字列の反復が含まれ、文字列のサイズに関しては一定時間ではありません。
  5. これらは人々が知っておくべきことです。
9
SLaks

ハッシュとその目的の簡単な説明をしようとします。

最初に、単純なリストを検討します。このようなリストの各操作(挿入、検索、削除)の複雑さはO(n)=複雑さです。つまり、リスト全体(または平均で半分)を解析して、そのようなことを実行する必要があります。操作。

ハッシュはそれを高速化する非常にシンプルで効果的な方法です。リスト全体を小さなリストのセットに分割することを考慮してください。このような小さなリスト内のアイテムには共通の何かがあり、この何かはキーから推測できます。たとえば、名前のリストを作成することにより、最初の文字をどの小さなリストで表示するかを選択する品質として使用できます。このように、キーの最初の文字でデータをパーティション分割することで、単純なハッシュを取得しました。これにより、リスト全体を〜30個の小さなリストに分割できるため、各操作にO(n)/ 30時間かかります。

ただし、結果はそれほど完璧ではないことに注意できます。最初に、それらは30のみであり、変更することはできません。第二に、いくつかの文字は他の文字よりも頻繁に使用されるため、YまたはZのセットはAのセットよりもはるかに小さくなります。より良い結果を得るには、アイテムをほぼ同じサイズのセットに分割する方法を見つけた方が良いでしょう。どうすればそれを解決できますか?ハッシュ関数を使用する場所です。これは、それぞれほぼ同じ数のアイテムを持つ任意の数のパーティションを作成できる機能です。名前のある例では、次のようなものを使用できます。

int hash(const char* str){
    int rez = 0;
    for (int i = 0; i < strlen(str); i++)
        rez = rez * 37 + str[i];
    return rez % NUMBER_OF_PARTITIONS;
};

これにより、非常に均一な分布と設定可能な数のセット(バケットとも呼ばれる)が保証されます。

5
ruslik
  1. ハッシュとは、特定のエンティティ(Java terms-オブジェクト)をある数(またはシーケンス)に変換することです。ハッシュ関数は元に戻せません-つまり、ハッシュから元のオブジェクトを取得することはできません。内部的に実装されます(_Java.lang.Object_の場合、JVMでメモリアドレスを取得します。

  2. JVMアドレスの事柄は重要ではありません。各クラスは、hashCode()メソッドを独自のアルゴリズムでオーバーライドできます。 Modren Java IDEでは、適切なhashCodeメソッドを生成できます。

  3. ハッシュテーブルとハッシュマップは同じものです。キーがハッシュされるキーと値のペア。ハッシュリストとハッシュセットは値を保存せず、キーのみを保存します。

  4. 一定時間とは、ハッシュテーブル(またはその他のコレクション)にエントリがいくつあっても、キーによって特定のオブジェクトを見つけるために必要な操作の数が一定であることを意味します。つまり-1、または1に近い

  5. これは基本的なコンピューターサイエンスの資料であり、誰もがそれに精通していることを前提としています。 Googleは、ハッシュテーブルがコンピューターサイエンスの最も重要なデータ構造であると指定していると思います。

5
Bozho

ハッシングとはどういう意味ですか、内部ではどのように機能しますか?

ハッシュとは、元の文字列を表す短い文字列の固定長値またはキーの変換です。インデックスを作成していません。ハッシュの中心はハッシュテーブルです。アイテムの配列が含まれます。ハッシュテーブルにはデータアイテムのキーからのインデックスが含まれ、このインデックスを使用してデータを配列に配置します。

どのアルゴリズムに従うのですか?

簡単な言葉で言えば、ほとんどのハッシュアルゴリズムは論理「index = f(key、arrayLength)」で機能します。

最後に、ほとんどのインタビュー質問でHashとLinkedListが尋ねられるのはなぜですか、インタビュー対象者の知識をテストすることから特定のロジックがありますか?

論理的推論の得意なところです。すべてのプログラマーが知っているのは、最も重要なデータ構造です。

0
user517400