問3 再帰の関数を配列の繰返しに直す

基本情報​技術者試験 令和8年度 公開問題 科目B、全6問のうちの問3。

出典:令和8年度 基本情報技術者試験 公開問題 科目B 問3(プログラムは原本の画像を文字に書き起こし、字下げは 1 段を空白 2 つで表した。空欄は[  ]で表した)

次のプログラム中の[  ]に入れる正しい答えを,解答群の中から選べ。ここで,配列の要素番号は 1 から始まる。

関数 func1 に与える引数と,関数 func2 に与える引数とが同じとき,二つの関数は同じ値を返す。プログラムでは,配列の領域外を参照してはならないものとする。

〔プログラム〕
○整数型: func1(整数型: n)
if (nが2以下)
return 1
endif
return 2 × func1(n - 2) + func1(n - 1)
 
○整数型: func2(整数型: n)
整数型の配列: data ← {1, 1, 1}
整数型: i
/* nが3より小さいときは繰返し処理を実行しない */
for (iを3からnまで1ずつ増やす)
data[1] ← data[2]
data[2] ← data[3]
data[3] ← [  ]
endfor
return data[3]
  1. ア2 × data[1] + data[2]
  2. イ2 × data[2] + data[1]
  3. ウ2 × data[i - 1] + data[i - 2]
  4. エ2 × data[i - 2] + data[i - 1]
  5. オdata[3] + 2 × data[1] + data[2]
  6. カdata[3] + 2 × data[2] + data[1]
  7. キdata[3] + 2 × data[i - 1] + data[i - 2]
  8. クdata[3] + 2 × data[i - 2] + data[i - 1]
答えと解説を開く

正解はアです。

func1 は、n が 2 以下なら 1、それより大きければ「2 つ前の値の 2 倍 + 1 つ前の値」を返します。func1(1) = 1、func1(2) = 1、func1(3) = 2 × 1 + 1 = 3、func1(4) = 2 × 1 + 3 = 5 です。func2 は、直前の値を data に持ちながら前へ進めます。繰返しの中で data[1] ← data[2]、data[2] ← data[3] と 1 つずつ前へ送ると、data[1] には 2 つ前の値、data[2] には 1 つ前の値が入ります。ここから新しい値を作るので、data[3] ← 2 × data[1] + data[2] です。n = 4 で追うと、i = 3 で data は {1, 1, 3}、i = 4 で {1, 3, 5} になり、func1(4) の 5 と合います。正解はアです。

ほかの選択肢が違う理由

  • イdata[2] を 2 倍しています。data[2] は 1 つ前の値なので、2 つ前を 2 倍する式になりません。n = 4 では {1, 3, 7} になり、5 と合いません。
  • ウdata の要素数は 3 なので、i が 5 以上になると data[i - 1] が配列の外を指します。i は回数を数える変数で、箱の番号ではありません。
  • エウと同じく、i が大きくなると data[i - 2] や data[i - 1] が配列の外を指します。
  • オ前の data[3] の値を余分に足しています。data[3] は送ったあと data[2] にも入っているので、1 つ前の値を 2 回足すことになります。
  • カ前の data[3] を余分に足し、さらに 2 倍する相手も違います。
  • キ前の data[3] を余分に足し、i を箱の番号に使うので配列の外も指します。
  • ク前の data[3] を余分に足し、i を箱の番号に使うので配列の外も指します。

仕組み

再帰の関数は、同じ計算を何度も繰り返すことがあります。func1(n) は func1(n - 1) と func1(n - 2) を呼び、その中でまた同じ値を求め直します。

直前のいくつかの値だけを箱に持って前へ送る形に直すと、各値を 1 回ずつしか求めません。これは動的計画法の考え方の入口です。

この問に出る言葉