令和5年度 科目B 問4
データ構造
ハッシュに関する問題
次の記述中の[ ]に入れる正しい答えを,解答群の中から選べ。ここで,配列の要素番号は 1 から始まる。
関数 add は,引数で指定された正の整数 value を大域の整数型の配列 hashArray に格納する。格納できた場合は true を返し,格納できなかった場合は false を返す。ここで,整数 value を hashArray のどの要素に格納すべきかを,関数 calcHash1 及び calcHash2 を利用して決める。
手続 test は,関数 add を呼び出して,hashArray に正の整数を格納する。手続 test の処理が終了した直後の hashArray の内容は,[ ]である。
〔プログラム〕
大域: 整数型の配列: hashArray
○論理型: add(整数型: value)
整数型: i ← calcHash1(value)
if (hashArray[i] = -1)
hashArray[i] ← value
return true
else
i ← calcHash2(value)
if (hashArray[i] = -1)
hashArray[i] ← value
return true
endif
endif
return false
○整数型: calcHash1(整数型: value)
return (value mod hashArrayの要素数) + 1
○整数型: calcHash2(整数型: value)
return ((value + 3) mod hashArrayの要素数) + 1
○test()
hashArray ← {5個の -1}
add(3)
add(18)
add(11)- ア{-1, 3, -1, 18, 11}
- イ{-1, 11, -1, 3, -1}
- ウ{-1, 11, -1, 18, -1}
- エ{-1, 18, -1, 3, 11}
- オ{-1, 18, 11, 3, -1}
答えと解説を見る
✓ これが正解エ{-1, 18, -1, 3, 11}
解説
3は4番目、18は2番目、11は5番目に入ります。
関数 add は、まず calcHash1 で格納先の要素番号を求め、そこが空き(-1)なら格納します。空いていなければ calcHash2 で別の要素番号を求め、そこが空きなら格納し、どちらも埋まっていれば false を返します。このように値から格納先を計算する方法をハッシュといいます。hashArray の要素数は 5 なので、calcHash1 は value mod 5 + 1、calcHash2 は (value + 3) mod 5 + 1 です。mod は割り算の余りです。
add(3) では 3 mod 5 + 1=4 なので、4番目に 3 が入ります。add(18) では 18 mod 5 + 1=4 となり、4番目はすでに 3 で埋まっています。そこで calcHash2 を使い、21 mod 5 + 1=2 なので、2番目に 18 が入ります。add(11) では 11 mod 5 + 1=2 となり、2番目は 18 で埋まっています。calcHash2 は 14 mod 5 + 1=5 なので、5番目に 11 が入ります。
したがって test の終了直後は {-1, 18, -1, 3, 11} です。異なる値から同じ格納先が計算されることを衝突といい、このプログラムでは、衝突が起きたときに2つ目のハッシュ関数で別の位置を求めて対処しています。
格納の順序と、埋まっていたときに2つ目の関数へ切り替える流れを1件ずつ追えば、格納先の取り違えを防げます。
ほかの選択肢はなぜ違うのか
- ア{-1, 3, -1, 18, 11}:3 と 18 の位置が逆です。この並びは add(18) を add(3) より先に実行した場合に得られます。実際は 3 が先に 4番目を取り、後から来た 18 が衝突して calcHash2 の 2番目に回ります。
- イ{-1, 11, -1, 3, -1}:18 が格納されていません。4番目が埋まっていたときに calcHash2 を試さず false を返すと、この並びになります。プログラムは2つ目の関数で 2番目を求めるので、18 はそこに入ります。
- ウ{-1, 11, -1, 18, -1}:3 が消えて 4番目が 18 になっています。空きかどうかを確かめずに calcHash1 の位置へ上書きすると、この並びになります。add は -1 と等しいときだけ格納するので、3 は上書きされません。
- オ{-1, 18, 11, 3, -1}:11 が 3番目に入っていますが、11 の格納先は calcHash1 では 2番目、calcHash2 では 5番目で、どちらの関数からも 3番目は導けません。2番目が埋まっているので、11 は 5番目に入ります。
この問題の用語
- ハッシュハッシュ関数で作られた値そのもの。元に戻せないので、中身を見せずに同じかどうかだけを確かめるのに使えます。
出典:令和5年度 基本情報技術者試験 科目B 問4
同じ用語が出る問題
- 平成31年度 春期 午前 問18:理想的なハッシュ法の説明(ハッシュ)
- 平成30年度 春期 午前 問7:表探索におけるハッシュ法の特徴(ハッシュ)
- 平成29年度 春期 午前 問27:ソートマージ結合法に関する記述(ハッシュ)
- 平成27年度 秋期 午前 問26:キー値に関する問題(ハッシュ)
- 平成26年度 秋期 午前 問27:ハッシュインデックスに関する問題(ハッシュ)
この解説に誤りを見つけたら教えてください。直して、直した記録を残します。誤りを報告する(メールが開きます)