基本情報技術者 2011年 秋期 午前(科目A) 問05
問題文
スタック1, 2があり、図の状態になっている。関数fはスタック1からポップしたデータをそのままスタック2にプッシュする。関数gはスタック2からポップしたデータを出力する。b, c, d, aの順番に出力するためには、関数をどの順で実行すればよいか。

選択肢
ア:f,f,g,f,f,g,g,g
イ:f,f,g,f,g,f,g,g(正解)
ウ:f,f,g,f,g,g,f,g
エ:f,f,g,g,f,f,g,g
スタックの操作順序を問う問題【午前2 解説】
要点まとめ
- 結論:正しい操作順は イ(f,f,g,f,g,f,g,g)で、出力順 b, c, d, a が得られます。
- 根拠:f は S1 からトップを取り S2 のトップに積む操作で、g は S2 のトップを出力する LIFO 特性を利用します。
- 差がつくポイント:S2 に積んだ直後に g を入れることで要素の相対順序を調整し、不要な反転を避けます。
正解の理由
選択肢 イ は f と g の順で S1→S2 という LIFO の転送と S2 からの出力を交互に行い、最終的に b, c, d, a の順に出力します。初期の S1 は上から a, b, c, d(a がトップ)であり、f を 2 回で a,b を S2 に積み、g で b を先に出力することで b が最初に出ます。以降も同様に必要なタイミングで f と g を組み合わせることで期待順序が得られます。
よくある誤解
- 「上の要素が a でなく d がトップだ」と誤認すると操作順序の判断を誤り、出力順が狂います。図の上端がトップと解釈する点を確認してください。
- 「f をまとめて多く実行すれば良い」と考えると S2 に余計な反転が生じ、出力順を崩します。必要な時に g を挟むのが肝心です。
- g が S1 から出力すると誤解するケース:g は常に S2 からしか出力しない点を忘れないでください。
解法ステップ
- 状態確認:S1 = [a(top), b, c, d], S2 = [] とする(上がトップ)。
- 目標は出力列 b, c, d, a。まず b を S2 のトップにする必要がある。
- 操作列 f,f,g,f,g,f,g,g を順に適用して検証する(下に詳細に示す)。
- 初期:S1 = [a, b, c, d], S2 = [], 出力 = []
- f → a を移動:S1=[b,c,d], S2=[a], 出力=[]
- f → b を移動:S1=[c,d], S2=[b,a], 出力=[]
- g → S2 から b を出力:S1=[c,d], S2=[a], 出力=[b]
- f → c を移動:S1=[d], S2=[c,a], 出力=[b]
- g → c を出力:S1=[d], S2=[a], 出力=[b,c]
- f → d を移動:S1=[], S2=[d,a], 出力=[b,c]
- g → d を出力:S1=[], S2=[a], 出力=[b,c,d]
- g → a を出力:S1=[], S2=[], 出力=[b,c,d,a]
選択肢別の誤答解説
- ア: f,f,g,f,f,g,g,g
2 回目以降に f を続けて S2 に多く積むため、出力は b, d, ... のように順序が崩れます(4〜6 手目で期待順と異なる)。 - イ: f,f,g,f,g,f,g,g
正解。上節の通り、各ステップで S2 のトップが期待する出力になるよう g を挿入しています。 - ウ: f,f,g,f,g,g,f,g
5〜6 手目で g を連続して a を早く出力してしまい、3 番目に a が出るため順序が b,c,a,… になって誤りです。 - エ: f,f,g,g,f,f,g,g
3〜4 手目で g を連続して a を早く出力してしまい、b の次に a が出るので誤りです。
補足コラム
- この問題は「スタック(LIFO)」の基本理解と、複数スタックを使った順序制御の練習問題です。S1→S2 の単純な転送は順序を反転させ、途中で出力(g)を挟むことで部分的に反転を解除できます。
- 一般に「二つのスタックを直列に使う」操作は、順序の全体的な変換(スタックパーミュテーション)を生み、出力可能な順列は制約を受けます。試験対策では図示されたトップ・ボトムの確認をまず行ってください。
FAQ
Q: トップは図の上側で確定ですか?
A: はい。本問では上端がスタックのトップと解釈します。問題文の図は上から a, b, c, d と配置されています。
A: はい。本問では上端がスタックのトップと解釈します。問題文の図は上から a, b, c, d と配置されています。
Q: f は何をする操作ですか?
A: f は S1 からポップした要素をそのまま S2 にプッシュ(S2 のトップへ積む)する操作です。
A: f は S1 からポップした要素をそのまま S2 にプッシュ(S2 のトップへ積む)する操作です。
Q: g はどのスタックから出力しますか?
A: g は常に S2 のトップをポップして出力します。S1 から直接出力はしません。
A: g は常に S2 のトップをポップして出力します。S1 から直接出力はしません。
Q: どのようにして正しい順序を設計すれば良いですか?
A: 目標出力の先頭要素が S2 のトップになるように、必要な要素だけ S1 から S2 に移してから g を入れることを繰り返します。
A: 目標出力の先頭要素が S2 のトップになるように、必要な要素だけ S1 から S2 に移してから g を入れることを繰り返します。
関連キーワード: スタック、LIFO、push、pop、スタック操作、スタックパーミュテーション、操作順序、アルゴリズム理解

\ せっかくなら /
基本情報技術者を
クイズ形式で学習しませんか?
クイズ画面へ遷移する→
すぐに利用可能!

