【科目B対策】ハッシュ法(ハッシュ探索)を擬似プログラミング言語で理解する
― 探索が一瞬で終わるアルゴリズム ―
はじめに
基本情報技術者試験・科目Bでは、
探索アルゴリズムとして次の3つが扱われます。
- 線形探索法
- ハッシュ法
- 2分探索法
この記事では、その中でも
「なぜ高速なのか」がポイントになるハッシュ法(ハッシュ探索)に絞って解説します。
ハッシュ法とは?
一言でいうと
ハッシュ法とは、探したいデータの「置き場所」を先に計算してしまう探索アルゴリズムです。
線形探索のように先頭から順番に調べるのではありません。
探索の考え方(超重要)
ハッシュ法では、次の流れで探索を行います。
- データを ハッシュ関数 に入れる
- ハッシュ値 を求める
- ハッシュ値を 配列の要素番号(アドレス) として使う
- その場所を直接確認する
👉 探す場所が最初から決まっている
これが最大の特徴です。
ハッシュ関数とは?
ハッシュ関数の役割
データ → 数値(ハッシュ値)に変換する仕組み
科目Bでは、次のような 非常にシンプルなハッシュ関数 がよく使われます。
ハッシュ値 = 入力値 mod 10
※ mod は「割り算の余り」を表します。
具体例で理解する(教科書準拠)
例:次のデータを格納する
| データ |
|---|
| 32 |
| 78 |
| 51 |
ハッシュ関数
x mod 10
ハッシュ値の計算
- 32 mod 10 → 2
- 78 mod 10 → 8
- 51 mod 10 → 1
ハッシュ表(配列)のイメージ
| 要素番号 | データ |
|---|---|
| 1 | 51 |
| 2 | 32 |
| 8 | 78 |
このように、
ハッシュ値 = データの格納場所
になります。
ハッシュ法による探索の流れ
例:32 を探す場合
- 探索対象「32」をハッシュ関数に入れる
- 32 mod 10 = 2
- 要素番号「2」を確認
- 一発で発見
👉 探索回数は1回
これが、ハッシュ法が高速な理由です。
擬似プログラミング言語でのイメージ
前提
- 配列 T はハッシュ表
- ハッシュ関数は KEY mod 10
擬似コード例
H ← KEY mod 10
if T[H] = KEY then
FOUND ← true
else
FOUND ← false
endif
読み取りポイント
- ループが存在しない
- 計算 → 1回比較だけ
- 「速い」理由を構造で理解する
(科目Bの擬似言語)だと、「全コード」は (1) ハッシュ表を作る(格納) と (2) 探す(探索) の両方を含む形になります。
ハッシュ関数:x mod 10、ハッシュ表:配列 T[0..9](空は EMPTY) として、衝突は“起きる”ところまで(解決法は試験範囲外になりやすい)を基本形にします。
1) 科目B向け:衝突解決なし(最小構成の全コード)
「衝突が起きたら格納失敗」とする、いちばんシンプルな形です。
// 定数
EMPTY ← -1
// ハッシュ関数
function Hash(x)
return x mod 10
endfunction
// ハッシュ表の初期化
procedure InitTable(T)
for i ← 0 to 9
T[i] ← EMPTY
endfor
endprocedure
// 格納(衝突解決なし)
function Insert(T, x)
h ← Hash(x)
if T[h] = EMPTY then
T[h] ← x
return true
else
// 衝突(コリジョン)
return false
endif
endfunction
// 探索
function Search(T, key)
h ← Hash(key)
if T[h] = key then
return true
else
return false
endif
endfunction
// メイン例(教科書データ)
procedure Main()
declare T[0..9]
InitTable(T)
Insert(T, 32)
Insert(T, 78)
Insert(T, 51)
print Search(T, 32) // true
print Search(T, 49) // false(格納していない想定)
endprocedure
このコードで、科目B的に重要なポイントはこれです。
- h ← key mod 10 が 格納場所(要素番号) を決める
- 探索は 1回のアクセス+1回の比較(速い理由)
- 弱点は Insert の else にある 衝突
2) 参考:衝突を解決する全コード(線形探索=線形プロービング)
科目Bでは「衝突が起きる」は問われやすい一方、解決法の詳細は深追いされにくいです
(空きが見つかるまで 次の場所へずらして格納)
EMPTY ← -1
function Hash(x)
return x mod 10
endfunction
procedure InitTable(T)
for i ← 0 to 9
T[i] ← EMPTY
endfor
endprocedure
// 格納(線形プロービング)
function Insert(T, x)
h ← Hash(x)
for k ← 0 to 9
idx ← (h + k) mod 10
if T[idx] = EMPTY then
T[idx] ← x
return true
endif
endfor
// 表が満杯
return false
endfunction
// 探索(線形プロービング)
function Search(T, key)
h ← Hash(key)
for k ← 0 to 9
idx ← (h + k) mod 10
if T[idx] = EMPTY then
// 途中で空が出たら、これ以上先には存在しない
return false
endif
if T[idx] = key then
return true
endif
endfor
return false
endfunction
procedure Main()
declare T[0..9]
InitTable(T)
Insert(T, 32) // 2
Insert(T, 42) // 2で衝突 → 3へ
Insert(T, 78) // 8
Insert(T, 51) // 1
print Search(T, 42) // true
print Search(T, 49) // false
endprocedure
どっちを「科目Bの全コード」として覚えるべき?
- 試験の本筋(速い理由・衝突が起きる)に絞るなら → 1) 衝突解決なし
- 授業で「衝突したらどうする?」まで見せたいなら → 2) 線形プロービング
ハッシュ法の弱点(試験に出る)
衝突(コリジョン)とは?
異なるデータなのに、同じハッシュ値になること
例
- 32 mod 10 → 2
- 42 mod 10 → 2
この場合、
- 同じ要素番号「2」に
- 2つのデータを格納できない
これを 衝突 と呼びます。
科目Bでの扱い方(重要)
基本情報技術者試験では、
- 「ハッシュ法のデメリットは衝突が起こる可能性があること」
- 衝突をどう解決するか(連鎖法・再ハッシュなど)
👉 解決方法の詳細は問われません
あくまで、
「衝突が起きる可能性がある」
という 性質の理解 がポイントです。
ハッシュ法の特徴まとめ
| 項目 | 内容 |
|---|---|
| 探索速度 | 非常に速い |
| 探索回数 | 原則1回 |
| 並び順 | 不要 |
| デメリット | 衝突が起こる可能性 |
科目B対策としての注意点
① ハッシュ値=要素番号
- ハッシュ値は「比較する値」ではなく「場所」
ここを混同すると誤読します。
② for文を探さない
ハッシュ法の問題では、
- ループがない
- または最小限
👉 「なぜ繰り返していないのか?」
を意識すると正解しやすくなります。
まとめ
- ハッシュ法は「探す場所を計算する」探索アルゴリズム
- 科目Bでは 速さの理由と衝突の存在 が理解できればOK
- 擬似プログラミング言語では計算 → 直接アクセス の流れを読む


ディスカッション
コメント一覧
まだ、コメントがありません