マナビング基本情報技術者

再帰呼び出しでスタックの値はどの順に移るか

基本情報技術者試験 平成31年度春期 午前 問6 / アルゴリズムとプログラミング › アルゴリズム

過去問にチャレンジ

平成31年度春期 午前 問6

三つのスタックA,B,Cのいずれの初期状態も[1,2,3]であるとき,再帰的に定義された関数ƒ()を呼び出して終了した後のBの状態はどれか。ここで,スタックが,[a1a_1 a2a_2,…,an−1a_{n-1}]の状態のときにana_nをpushした後のスタックの状態は[a1a_1 a2a_2,…,an−1a_{n-1},ana_n]で表す。 ƒ(){ Aが空ならば{ 何もしない。 } そうでない場合{ Aからpopした値をCにpushする。 ƒ()を呼び出す。 Cからpopした値をBにpushする。 } }

  1. ア

    [1,2,3,1,2,3]

  2. イ

    [1,2,3,3,2,1]

  3. ウ

    [3,2,1,1,2,3]

  4. エ

    [3,2,1,3,2,1]

会話形式の解説

講師講師
この問題は、Aから取り出す順番と、Bに積む順番を分けて追うのがポイントです。
受験者受験者
Aの右端から3、2、1を取り出すので、Bにもその順で入ると思いました。
講師講師
CからBへ移す処理は、再帰呼び出しの前と後のどちらにありますか。
受験者受験者
後です。まずAが空になるまで呼び出しが続きます。
講師講師
そうです。その間、Aから取り出した3、2、1をCに積みます。
受験者受験者
Aが空になって戻るときは、Cの右端にある1から取り出すのですか。
講師講師
はい。戻る順にCから1、2、3を取り出し、Bに積みます。
受験者受験者
Bは初めから[1,2,3]なので、終了時は[1,2,3,1,2,3]ですね。
講師講師
その通りです。後ろに3、2、1が続く候補は、Bへの追加順を逆に考えています。
受験者受験者
先頭が[3,2,1]の二つの候補は、Bの初期状態とも違います。
講師講師
はい。Bの既存の値は取り出さないので、先頭の[1,2,3]は残ります。両方とも[3,2,1]の候補は、追加順も違います。
受験者受験者
Cも初めから[1,2,3]ですが、その値はBに移らないのですね。
講師講師
AからCに積んだ値を戻る途中ですべて取り出すため、Cの初期要素は残ります。再帰呼び出しより後の処理は、深い呼び出しから戻る順に追うと分かりやすいです。

まとめ

Aからは右端の3、2、1を順に取り出し、Cに積みます。再帰呼び出しから戻るとき、CからBへ移る順番は1、2、3です。Bの初期状態[1,2,3]は変わらないので、終了時のBは[1,2,3,1,2,3]となり、正解はアです。Cの初期要素はBへ移りません。

解答・解説

正解はアです

この問題のテーマ

再帰呼び出しでスタック間の値が移る順序と、処理後のBの状態を問う問題です。

解き方の考え方

スタックでは右端の値をpopします。Aからは3、2、1の順に取り出してCに積み、そのたびに次のƒ()を呼び出します。Aが空になると呼び出し元へ順に戻り、各回でCからBへの移動が行われます。

選択肢ごとの解説

  1. ○ア  [1,2,3,1,2,3]
    CからBへ移る値は1、2、3の順です。Bの初期状態[1,2,3]の右側にこの順で追加するので、終了時は[1,2,3,1,2,3]になります。
  2. ×イ  [1,2,3,3,2,1]
    この並びは、Bに3、2、1の順で追加した場合の状態です。実際には再帰呼び出しから戻るときに1、2、3の順で追加します。
  3. ×ウ  [3,2,1,1,2,3]
    先頭の[3,2,1]がBの初期状態と一致しません。この関数はBの既存の値を取り出さないため、最初の[1,2,3]はそのまま残ります。
  4. ×エ  [3,2,1,3,2,1]
    Bの初期部分を[3,2,1]としている点が違います。また、Bへの追加部分も[3,2,1]ですが、実際の追加順は1、2、3です。

補足

Cにも最初から[1,2,3]が入っていますが、Aから積んだ値を戻る途中ですべて取り出すため、Cの初期要素はBへ移りません。

POINT

  • この表記のスタックでは、右端の値が次にpopされます。
  • 再帰呼び出しより前の処理は、深い呼び出しへ進むたびに実行されます。
  • 再帰呼び出しより後の処理は、深い呼び出しから戻る順に実行されます。

※出典:平成31年度春期 基本情報技術者試験 午前 問6