基本情報技術者試験 科目Bの「令和4年度(12月公開) サンプル問題 問3」(配列・繰り返しで累積和を作る makeNewArray)を、図解トレースで解説します。
本番を意識して、5分以内に解くことを目標に、効率的なトレースのやり方を学びましょう。
特に、ポイントは繰り返しのトレースです。
Point:10分以上かけるやり方は意味がない
本番では、100分で20問を解き、6割以上を得点する必要があります。
10分以上かけて解くようなやり方を学んでも、本番での得点に繋がらず無意味です。
(他の問題を解く時間がなくなるので、むしろ学ばない方がマシかもしれません)
この問題に限らず、本番に使える解法を学びましょう。
すさまじく丁寧にトレースするやり方の解説も見かけますが・・それらは試験対策ではなく、より理解を深めたいときに活用しましょう。
動画で見たい方はこちら▼
問題(令和4年度 サンプル問題 問3)
次の記述中の【 】に入れる正しい答えを,解答群の中から選べ。
ここで,配列の要素番号は 1 から始まる。
関数 makeNewArray は,要素数 2 以上の整数型の配列を引数にとり,整数型の配列を返す関数である。関数 makeNewArray を makeNewArray({3, 2, 1, 6, 5, 4}) として呼び出したとき,戻り値の配列の要素番号 5 の値は【 】となる。
○ 整数型の配列: makeNewArray(整数型の配列: in)
整数型の配列: out ← {} // 要素数0の配列
整数型: i, tail
outの末尾に in[1] の値を追加する
for (i を 2 から inの要素数 まで 1 ずつ増やす)
tail ← out[outの要素数]
outの末尾に (tail + in[i]) の結果を追加する
endfor
return out
解答群
ア 5 イ 6 ウ 9 エ 11 オ 12 カ 17 キ 21
本番さながらの環境で解いてみたい方はこちら↓
解説
正解は カ 17 です。
求められているのは戻り値そのものではなく、戻り値の配列の要素番号 5 の値です。out[5] の値が判明するまでトレースすればOK、ということをトレース前に確認しておきます。
①配列表を作成
in
| 1 | 2 | 3 | 4 | 5 | 6 |
|---|---|---|---|---|---|
| 3 | 2 | 1 | 6 | 5 | 4 |
②outの末尾に in[1] の値を追加する
out
| 1 |
|---|
| 3 |
for に入る前に1つ追加されます。繰り返し処理に気を取られて、途中の処理を見落としやすいので気を付けましょう。
③トレース表を作成
繰り返しの中身は、次の2行です。
tail ← out[outの要素数]
outの末尾に (tail + in[i]) の結果を追加する
この2行を1行にまとめるとoutの末尾に (out[outの要素数] + in[i]) の結果を追加するとなります。
まとめた状態でトレースします。
| i (2~6) | outの末尾に(out[outの要素数] + in[i]) |
|---|---|
| 2 |
実際のトレース時は o[末]にo[要]+in[i] など、自分が分かる形で省略して書きましょう。
「結果を追加する」は省略しています。ただし←だと代入と同じになってしまうのでoutの末尾「に」と記載しています。
④iに注目してトレース
最初に全繰り返し分の式を書いてしまいます。
iがどこかに注目すると、以下のようにトレースできます。
| i (2~6) | outの末尾に(out[outの要素数] + in[i]) |
|---|---|
| 2 | o[末]にo[要]+in[2] |
| 3 | o[末]にo[要]+in[3] |
| 4 | o[末]にo[要]+in[4] |
| 5 | o[末]にo[要]+in[5] |
| 6 | o[末]にo[要]+in[6] |
実際のトレース時は、変化のない繰り返し部分は「〃」などで省略してもOKです。
記号を使う場合は、処理ごと(取り消し線を引く単位) に書きましょう。複数の処理をまとめてしまうと、どの計算がおわったのかわかりにくくなります。
(〃を使った例)
| i (2~6) | outの末尾に(out[outの要素数] + in[i]) |
|---|---|
| 2 | 〃に〃+in[2] |
| 3 | 〃に〃+in[3] |
| 4 | 〃に〃+in[4] |
| 5 | 〃に〃+in[5] |
| 6 | 〃に〃+in[6] |
(実際のトレースイメージ)

outの末尾 や out[outの要素数] が何を指すのか、上から順に丁寧にトレースして計算します。
| i (2~6) | outの末尾に(out[outの要素数] + in[i]) |
|---|---|
| 2 | o[末]にo[要]+in[2] 3 + 2 5 |
| 3 | o[末]にo[要]+in[3] 5 + 1 6 |
| 4 | o[末]にo[要]+in[4] 6 + 6 12 |
| 5 | o[末]にo[要]+in[5] 12 + 5 17 |
| 6 | o[末]にo[要]+in[6] |
out
| 1 | 2 | 3 | 4 | 5 |
|---|---|---|---|---|
| 3 | 5 | 6 | 12 | 17 |
out[5] は 17(カ)です。
求めるのは 戻り値の配列の要素番号 5 の値 なので、i が6になるまで繰り返す必要はありません。
前の計算結果が次の計算に影響します。
必ず、上から順に計算しましょう。
Memo:(参考)式をまとめずに、分けてトレースした場合
③で2行を1行にまとめましたが、まとめずに tail の列を分けてトレースしてもOKです。
| i(2~6) | tail | outの末尾に(tail + in[i]) |
|---|---|---|
| 2 | 3 |
o[末]に(tail + in[2]) 3 + 2 5 |
| 3 | 5 |
o[末]に(tail + in[3]) 5 + 1 6 |
| 4 | out[3] 6 |
o[末]に(tail + in[4]) 6 + 6 12 |
| 5 | out[4] 12 |
o[末]に(tail + in[5]) 12 + 5 17 |
Point: 何が問われているのかをまず確認する
本番では、実行結果以外も問われることがあります。
- 配列の○番目の要素の値
- 特定の行を何回繰り返したか
- 条件判定が何回真になるか
「何が問われているのか」を始めに確認すると、途中のトレースを省略するなど、より効率的に正解できます。
Memo: 配列[配列の要素数] は配列の末尾の値を指す
out[outの要素数] のように 配列[配列の要素数] は、その配列の 末尾の値 を指します。out の要素数が1なら out[1]、4つなら out[4] の値です。
| 1 | 2 | 3 | 4 | 5 | 6 |
|---|---|---|---|---|---|
| 3 | 5 | 6 | 12 | 17 | 21 |
上の場合、out[outの要素数] は out[6]、つまり末尾の値21です。登場頻度は少ないので覚えなくてOK。知っているかどうかより、トレードしながら「つまり末尾の値だな」と読み替えられること(あるいは読み替えられなくてもトレースで正解を導けること)が重要です。
Memo: (別解)配列 out の値は、その要素数までの累計
アルゴリズムの本質的な話で、合格にここまでの理解は必要ありません。おまけ程度に聞いてください。
トレース表のとおり、out[] の値には次の計算式が成り立ちます。out[1] は in[1] なので、out[2] の out[1]+in[2] は in[1]+in[2] に置き換えられます。同様に out[3] は in[1]+in[2]+in[3]。整理すると次のとおり。
| out | 計算式 | 計算式の内訳 |
|---|---|---|
| out[1] | in[1] | |
| out[2] | out[1]+in[2] | in[1]+in[2] |
| out[3] | out[2]+in[3] | in[1]+in[2]+in[3] |
| out[4] | out[3]+in[4] | in[1]+in[2]+in[3]+in[4] |
| out[5] | out[4]+in[5] | in[1]+in[2]+in[3]+in[4]+in[5] |
| out[6] | out[5]+in[6] | in[1]+in[2]+in[3]+in[4]+in[5]+in[6] |
つまり out[x] には、in[1] から in[x] までの累計値が格納されています。out[5] は in[1]〜in[5] の累計なので、in が {3, 2, 1, 6, 5, 4} なら 3+2+1+6+5=17 が答えです。
まとめ
この問題の最大のポイントは、先に式を書いてしまい、後で一気に計算することです。
式を書いて計算して、式を書いて計算して・・と、都度計算するよりもずっと早く正解できます。
関連リンク

関連動画
配列&繰り返しの基礎が学べる、同じ章の動画です。
講座の全動画はこちら(プレイリスト)。

