令和5年度の科目B、その4問目です。プログラムは長く見えますが、難しい問題ではありません。解けるかどうかは、関数の呼び出しを順にたどれるか ── これだけで決まります。途中で出てくる計算は mod(割った余り)に 1 を足すだけです。この記事では、何ができれば解けるかを先に言い、そのあと 処理がどういう順番で進むかをトレース表でたどります。
出題
まず原文のまま読んでみてください。記号の読み方は次の節にまとめてありますので、読めなくてもここでは問題ありません。
出典:令和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})です。
この問題に出てくる記号
読めない記号があったときだけ開いてください。
擬似言語の記号 7コ の読み方をひらく
| 書き方 | 読み方 |
|---|---|
○論理型: add(…) |
ここから add という関数が1つ始まるという宣言です。置いてあるだけで、呼ばれるまで1行も実行されません。論理型 は返す値が true か false、整数型 は整数を返す、という意味です |
calcHash1(value) |
○ が付いていない名前は呼び出しです。その関数の中へ入り、return で返ってきた値を持って呼んだ行へ戻ります |
大域: 整数型の配列: hashArray |
どの関数からも同じ1つが見える配列。add が書き込んだ内容は、次に add が呼ばれたときも残っています |
hashArray[i] ← value |
hashArray の i 番目の要素に value を入れる(← は代入)。要素番号は1から数えます |
if (…) … else … endif |
かっこの中が真ならすぐ下を、偽なら else の下を実行します |
value mod 5 |
value を 5 で割った余り。余りは 0〜4 のどれかです |
{5個の -1} |
5つの要素をすべて -1 にした配列。この問題では -1 は、まだ何も入っていないことを表す目印です |
記号でつまずいたら、下の教科書から、先にそこだけ読んでください(G3 のような番号は、当サイトの擬似言語の教科書の第何回かを表します)。
何ができれば解けるか ── 呼び出しをたどるだけ
関数は4つ並んでいますが、上から順に実行されるわけではありません。問題文が「手続test は,関数add を呼び出して」と言っているので、動き出すのはいちばん下の test です。あとは呼び出しに出会うたびに、その関数の中へ入り、return で呼んだ行へ戻ってきます。
この問題で必要なこと
test から始めて、呼び出しの先へ入って計算し、呼んだ行へ戻る ── これを順にたどれれば解けます。
test から呼び出しの順にたどって、hashArray の中身を決める
下の「次へ」を押すと、test の1行目から1行ずつ進みます。見るのは3つです。
- 光っている行 ── いま実行している行。呼び出しのたびに、関数から関数へ飛びます
- いる場所 ── いまどの関数の中にいるか。右へ伸びたら中へ入った、短くなったら
returnで戻った、という意味です hashArrayの5マス ── どこが埋まったか
add が1回終わるたびに、いちばん下のトレース表に1行ずつ積み上がります。
1行ずつ追う add(3) → add(18) → add(11)
出典:令和5年度 科目B 公開問題 問4
ループ開始前
配列
いま計算していること
変数の状態
hashArray の最終状態
トレース表(進めると1行ずつ積み上がります)
1つ目の場所がふさがっていたときだけ calcHash2 へ進み、隣の空きは探しません。3回の add が終わって残るのは {-1, 18, -1, 3, 11} です。
答え合わせ
残った {-1, 18, -1, 3, 11} は、解答群の エ です。
取り違えやすいのは オ(11が3番目)です。ぶつかったときに隣の空きを探すとこうなりますが、このプログラムは隣を見ず、calcHash2 が返した番号(5)へ行きます。
次に読む
この問題でどこに手間取ったかで、行き先が変わります。
この記事で引用した資料
いずれも独立行政法人情報処理推進機構(IPA)が公表したものです。IPAは公表済みの試験問題について、教育目的での使用に許諾および使用料を不要としていますが、著作権は放棄していません。本記事では問題文を改変せずに引用しています。

