空欄は return の式1つですが、選択肢の中で factorial がまた factorial を呼んでいて、式を眺めるだけでは決めにくい問題です。そこで n に数を入れて6つとも計算し、おかしいものから消していきます。
難易度 ★(当サイトの目安)── 階乗の決まりを、そのまま1行の再帰に写すだけ。4段階の決め方は科目B 最短合格の戦略にあります。
出題
出典:基本情報技術者試験 科目B サンプル問題 問7
次のプログラム中の に入れる正しい答えを,解答群の中から選べ。
関数factorial は非負の整数n を引数にとり,その階乗を返す関数である。非負の整数n の階乗はn が0 のときに1 になり,それ以外の場合は1 からn までの整数を全て掛け合わせた数となる。
〔プログラム〕
○整数型: factorial(整数型: n)
if (n = 0)
return 1
endif
return
解答群
ア (n - 1) × factorial(n)イ factorial(n - 1)
ウ nエ n × (n - 1)
オ n × factorial(1)カ n × factorial(n - 1)
答えだけ先に見る
正解は カ(n × factorial(n - 1))です。
この問題に出てくる記号
読めない記号があったときだけ開いてください。
擬似言語の記号 3コ の読み方をひらく
| 書き方 | 読み方 |
|---|---|
○整数型: factorial(整数型: n) |
ここから関数 factorial が始まるという印。整数を1つ受け取って n と名前を付け、整数を1つ返します |
if (n = 0) 〜 endif |
n が 0 のときだけ、あいだの行を実行する |
return ◯ |
◯ の値を返して、関数を終える |
コードは何をしているか
〔プログラム〕
○整数型: factorial(整数型: n)
if (n = 0)
return 1
endif
return
※ 上の〔プログラム〕からの抜粋です(1字も変えていません)。
n が 0 なら 1 を返して終わり。それ以外は空欄の式を返します。factorial(4) なら、1 × 2 × 3 × 4 = 24 を返さなければなりません。
選択肢には factorial(n - 1) のように、factorial の中でまた factorial を呼ぶ式があります。読み方はほかの関数の呼び出しと同じで、factorial を最初から実行し、返ってきた値をその場所に入れるだけです。たとえば factorial(0) は、if で 1 を返します。
ここが大事です。選択肢を試すときは、中で呼ぶ factorial にもその同じ選択肢が入っています。中の factorial もその選択肢で計算します。
空欄に入るものを決める ── n = 4 で6つとも計算する
まず小さい n で試し、正しい値になるものが2つ以上残ったら、n を1つ増やしてもう一度試します。n = 2(正しい値は 2)ではウ・エ・カの3つ、n = 3(正しい値は 6)ではエ・カの2つが残るので、n = 4(正しい値は 24)まで進みます。アとオは n をいくつにしても終わらないので、一度消せば計算し直さなくて済みます。
factorial(4) を6つの選択肢で計算する
ア (n - 1) × factorial(n) → 終わらないので消去
factorial(4) = 3 × factorial(4) (中の)factorial(4) = 3 × factorial(4) …(同じ呼び出しが続く)
factorial(4) の中で factorial(4) をもう一度呼んでいます。n が小さくならないので、終わりません。
イ factorial(n - 1) → 1 で外れ
factorial(4) = factorial(3) = factorial(2) = factorial(1) = factorial(0) = 1
呼び出しを次へ渡すだけで、何も掛けていません。最後の factorial(0) の 1 がそのまま返ります。
ウ n → 4 で外れ
factorial(4) = 4
n をそのまま返すだけです。
エ n × (n - 1) → 12 で外れ
factorial(4) = 4 × 3 = 12
掛けているのは n と n - 1 の2つだけです(n = 3 ならたまたま 6 で一致します)。
オ n × factorial(1) → 終わらないので消去
factorial(4) = 4 × factorial(1) (中の)factorial(1) = 1 × factorial(1) …(同じ呼び出しが続く)
中の factorial(1) にもオが入っているので、factorial(1) は 1 × factorial(1)。factorial(1) がまた factorial(1) を呼び、終わりません(factorial(1) は 1 だから答えは 4、と考えると、ここを見落とします)。
カ n × factorial(n - 1) → 24 で正しい
factorial(4) = 4 × factorial(3) = 4 × 3 × factorial(2) = 4 × 3 × 2 × factorial(1) = 4 × 3 × 2 × 1 × factorial(0) = 4 × 3 × 2 × 1 × 1 = 24
n が1つずつ小さくなって factorial(0) で止まり、4 から 1 までが全部掛かります。
24 になったのはカだけです。アとオは計算が終わらない時点で、イ・ウ・エは値が 24 でない時点で消せます。
答え合わせ
正解は カ です。
カの n × factorial(n - 1) は、n の階乗 = n × (n - 1 の階乗) をそのまま書いた形です。factorial(4) から 0 まで呼び出しが重なり、戻りながら掛け算が進むのを1行ずつ見ます。
1行ずつ追う 正解の カ で factorial(4)
出典:科目B サンプル問題 問7(空欄に カ を入れたもの)
ループ開始前
いま計算していること
変数の状態
factorial(4) が返した値
トレース表(進めると1行ずつ積み上がります)
次に読む
この問題でどこに手間取ったかで、行き先が変わります。
この記事で引用した資料
いずれも独立行政法人情報処理推進機構(IPA)が公表したものです。IPAは公表済みの試験問題について、教育目的での使用に許諾および使用料を不要としていますが、著作権は放棄していません。本記事では問題文を改変せずに引用しています。

