ハッシュ探索法を分かりやすく解説!

皆さんは、大量のデータの中から目的のデータを探す時、どのように探しますか?

例えば、図書館で特定の本を探したい時、本のタイトルを一冊ずつ確認していくのは大変ですよね? そんな時に役立つのがハッシュ探索法です!

ハッシュ探索法とは?

ハッシュ探索法は、データをハッシュテーブルと呼ばれる特別な表に格納し、高速に検索するアルゴリズムです。

イメージとしては、図書館の本を著者名順ではなく、特別なルールに基づいて配置する感じです。

このルールをハッシュ関数と呼びます。ハッシュ関数は、データ(例えば本のタイトル)を受け取り、ハッシュテーブルの**特定の位置(インデックス)**を計算します。

ハッシュ探索法の仕組み

  1. ハッシュ関数でインデックスを計算: 探したいデータ(例えば「ハッシュ探索法入門」という本)をハッシュ関数に入力します。すると、ハッシュ関数は「15」というインデックスを返します。
  2. 計算されたインデックスの場所にアクセス: ハッシュテーブルの15番目の場所にアクセスします。
  3. データが存在するか確認: 15番目の場所に「ハッシュ探索法入門」の本があれば、探索成功です!

ハッシュ探索法のメリット

  • 探索が高速: データ量が増えても、探索にかかる時間はほぼ変わりません! これは、ハッシュ関数によって直接目的のデータに近い場所にアクセスできるからです。

ハッシュ探索法のデメリット

  • 衝突の発生: 異なるデータがハッシュ関数によって同じインデックスに割り当てられることがあります。これを衝突と言います。
  • 衝突の解決: 衝突が発生した場合は、別の方法でデータを格納する必要があります。例えば、同じインデックスにリストを作ってデータを繋げたり、空いている別の場所にデータを格納したりします。

ハッシュ探索法の例

例えば、学生のIDと名前を管理するシステムを考えてみましょう。

ID名前
123田中太郎
456佐藤花子
789鈴木一郎

ハッシュ関数として「IDを3で割った余り」を使うと、

  • 田中太郎(ID:123)は、123 ÷ 3 の余りが 0 なので、インデックス 0 に格納されます。
  • 佐藤花子(ID:456)は、456 ÷ 3 の余りが 0 なので、インデックス 0 に格納されます。 衝突発生!
  • 鈴木一郎(ID:789)は、789 ÷ 3 の余りが 0 なので、インデックス 0 に格納されます。 衝突発生!

この場合、インデックス 0 にリストを作成し、[田中太郎, 佐藤花子, 鈴木一郎]のようにデータを格納することで衝突を解決できます。

まとめ

ハッシュ探索法は、大量のデータから目的のデータを高速に検索できる便利なアルゴリズムです。

ただし、衝突が発生する可能性があるため、衝突の解決策も合わせて理解しておくことが重要です

Javaでのハッシュテーブルの実装と検索方法

ハッシュテーブルは、効率的なデータの格納と検索を実現するために広く使用されるデータ構造です。この記事では、Javaでハッシュテーブルを実装し、特定の値を検索する方法を紹介します。

問題の概要

以下のようなコードで、配列を使ってハッシュテーブルを実装しようとしたとき、うまく動作しないことがあります。

public static void main(String[] args) throws Exception {
    int[] nums = {1, 3, 5, 6, 7, 10, 20};
    int[] hashNums = new int[nums.length];
    
    for(int i=0; i<hashNums.length; i++){
        int hashNum = nums[i] % 7;
        hashNums[hashNum] = nums[i];
        System.out.println(hashNums[hashNum] + " ");
    }
    
    // 検索したい値
    int val = 5;
    int valHash = val % 7;
    System.out.println("検索値:" + valHash + " 添え字:" + valHash);
}




このコードでは、同じハッシュ値に対して複数の値が格納される可能性があるため、正しくハッシュ検索ができません。

解決方法:リストを使用した衝突解決

ハッシュテーブルの衝突を避けるためには、各ハッシュ値に複数の値を格納できるようにする必要があります。ここでは、ArrayList を使用して実装する方法を紹介します。

ArrayListを使用したハッシュテーブルの実装

以下のコードは、ArrayList を使ってハッシュテーブルを実装し、値を格納する例です。

import java.util.ArrayList;

public static void main(String[] args) throws Exception {
    int[] nums = {1, 3, 5, 6, 7, 10, 20};
    ArrayList<Integer>[] hashTable = new ArrayList[7]; // 7はハッシュテーブルのサイズ

    // 初期化
    for (int i = 0; i < hashTable.length; i++) {
        hashTable[i] = new ArrayList<>();
    }

    // ハッシュテーブルへの格納
    for (int i = 0; i < nums.length; i++) {
        int hashNum = nums[i] % 7;
        hashTable[hashNum].add(nums[i]);
    }

    // ハッシュテーブルの内容を表示
    for (int i = 0; i < hashTable.length; i++) {
        System.out.println("Index " + i + ": " + hashTable[i]);
    }

    // 検索したい値
    int val = 5;
    int valHash = val % 7;
    if (hashTable[valHash].contains(val)) {
        System.out.println("検索値: " + val + " はハッシュテーブルのインデックス " + valHash + " に存在します。");
    } else {
        System.out.println("検索値: " + val + " はハッシュテーブルに存在しません。");
    }
}




コードのポイント

  1. 初期化: ArrayList の配列を作成し、各インデックスに空のリストを初期化します。
  2. 値の格納: 配列 nums の各値に対してハッシュ値を計算し、そのハッシュ値に対応する ArrayList に値を追加します。
  3. 検索: 検索したい値に対してハッシュ値を計算し、対応する ArrayList にその値が存在するかどうかを確認します。

結果

この方法を用いることで、ハッシュ値が衝突した場合でも、値を正しく格納および検索できるようになります。

結論

ArrayList を使用することで、ハッシュテーブル内で同じインデックスに複数の値を持つことができ、衝突を効果的に処理できます。Javaでハッシュテーブルを実装する際には、データの格納方法と検索方法を考慮することが重要です。

LibGDX 環境構築手順【備忘録】

1. LibGDX Setup Appのダウンロード

LibGDXのプロジェクトを作成するためのツールをダウンロードします。

  • LibGDXの公式サイトから「Setup App」をダウンロード。
  • ダウンロードした gdx-setup.jar または gdx-liftoff.exe を実行。

2. LibGDXプロジェクトの作成

Setup Appを使ってLibGDXプロジェクトを作成します。

  • LIBGDX VERSION: 最新版が選ばれているのを確認。
  • JAVA VERSION: 11 を選択(デフォルト)。
  • APP VERSION: 1.0.0 のままでOK。
  • ADD GUI ASSETS: チェックしなくてもOK(GUIアセットが必要ならチェック)。
  • ADD README: 必要に応じてチェック。

プロジェクト保存場所の設定

  • PROJECT PATH: プロジェクトを保存したい場所を指定。デスクトップやドキュメントフォルダなど、わかりやすい場所を選びましょう。

: C:\Users\YourName\Desktop\LibGDXProjects\MyFirstGame

  • Generate ボタンを押してプロジェクトを生成。

5. プロジェクトのインポート

EclipseやIntelliJ IDEAにLibGDXプロジェクトをインポートします。

  • Eclipseの場合:
    1. Eclipseを開き、「File」 > 「Import」を選択。
    2. 「Gradle」 > 「Existing Gradle Project」を選び、「Next」をクリック。
    3. プロジェクトを保存したディレクトリを指定してインポート。

6. 必要なアドオンの追加

簡単なゲームを作成する場合、以下のアドオンを追加するのが良いです。

  • Box2D: 2D物理エンジンを使いたい場合。
  • FreeType: カスタムフォントを使いたい場合。

サードパーティのアドオンは通常不要。必要になったら後で追加を検討する程度でOK。

7. ゲーム作りのスタート

プロジェクトをインポートしたら、DesktopLauncher.java を実行して、LibGDXのデフォルトプロジェクトが正しく動作するか確認。