[WIL]ハッシュ表


1.スケジュールとは?


  • ハッシュテーブルは、ハッシュ関数を用いてキー値を演算し、固定長の結果値を得、これらの結果値を用いてキー値をマッピングする形式のデータ構造である.

  • このように、ハッシュ関数を用いてキーと値をマッピングすることをハッシュと呼び、ハッシュは情報を迅速に格納および取得するための重要な技術である.

  • apple -> 10
    orange -> 00
    banana -> 01
    これにより、キー値を入力すると、固定長のハッシュ値が得られ、その値を用いてデータが格納され、取得される.
  • 2.ハッシュ値が競合する場合


  • コンフリクト
    異なる値のキー値を計算すると、同じ結果を示すハッシュ値が競合します.
    衝突する確率はどのくらいですか?
    衝突を説明する際によく使われる例として、誕生日問題が挙げられる.

  • 誕生日の質問
    年は365日、人が持つことができる誕生日は365種類に達する.
    では、同じ誕生日を過ごした人は何人いますか.100名?200人?
    できなくても、100人以上の人が同じ誕生日を持つことができると考えられています.
    しかし、23人だけが集まっていても、同じ誕生日を持つ人がいる確率は50%を超えています.
    また、57人を超える場合は99%を超える.
    これをハッシュに代入し,ハッシュで得られる結果値365個があれば23個のデータを入れると衝突する確率は50%以上,57個のデータを入力するとほぼ100%の確率で衝突する.

  • 衝突が発生した場合
    では、衝突が発生した場合、どのように対応しますか?
    ハッシュ・テーブルでは、競合の解決方法は大きく2つに分けることができます.
    リンクとオープンアドレス方式.
  • 2-1. chaining

  • 最初のリンク方式は、競合するデータをチェーンテーブル資料構造に形成し、記憶することである.
  • りんごとバナナが衝突し、スケジュール(10)にバナナをリンクリストで保存します.
  • 2-2. open addressing

  • 競合が発生した場合、hashテーブルの空き領域に値が格納されます.
  • appleとbananaは衝突し、ハッシュテーブルで空き空間を決定し、バナナをこの空間(11)に格納する.
  • 3. hash table[python]


  • 白準1920号で問題を探してハッシュテーブルとは何かを知る
    1920題は4行目に入力された値が2行目に入力された値の間に含まれているかどうか、含まれている場合は1がなければ0を出力するプログラムです.

  • イニシャルコミットコード
    次のコードをバックグラウンドにコミットすると正常に動作します.
    ただし所要時間が4000 msを超えることが確認できます.
  • # 정수 A의 개수 n 입력
    n = int(input())
    # 정수 A 입력
    a = list(map(int,input().split(" ")))
    # A안에 존재하는지 확인할 정수의 개수
    m = int(input())
    # 확인할 정수 입력
    values = list(map(int, input().split(" ")))
    # list의 정수를 하나씩 a에 존재하는지 확인
    # 존재한다면 1 존재하지 않는다면 0을 출력
    for v in values:
        if v in a:
            print('1')
        else:
            print('0')
  • ハッシュ・テーブルを使用するコード
    上記のコードと同様の動作ですが、かかる時間は200ミリ秒に大幅に減少しました.
    ただし、次のコードでは、2行目の入力値を受信するデータ型がlistからsetに変更されていることがわかります.
    ここで使用するsetはhash tableです.
    pythonでは、デフォルトのデータ型setはhashテーブルで作成されたデータ型であり、既存のlistでは、listにこの数字が含まれているかどうかを決定するために、listの値を1つずつ比較して、同じ値が存在するかどうかを決定することができ、時間複雑度O(n)の時間がかかる.
    ただし,setデータ型を用いて入力したキー値をハッシュして直接値にアクセスするため,O(1)の時間的複雑さがある.
  • # 정수 A의 개수 n 입력
    n = int(input())
    # 정수 A 입력
    a = set(map(int,input().split(" ")))
    # A안에 존재하는지 확인할 정수의 개수
    m = int(input())
    # 확인할 정수 입력
    values = list(map(int, input().split(" ")))
    # list의 정수를 하나씩 a에 존재하는지 확인
    # 존재한다면 1 존재하지 않는다면 0을 출력
    for v in values:
        if v in a:
            print('1')
        else:
            print('0')
  • 題では,入力値が多くないため速度差が20倍程度あるが,入力値の数が増えると速度差が大きくなる.