基本情報技術者試験 令和6年 科目B 問4「merge関数の動作」の考察

FE対策

はじめに

試験問題に取り組んでいて、何気なく「merge関数の動作」を問う問題を見たことがあるだろうか?
一見、単純な処理のように思えるが、実際にコードを読み解いてみると奥が深い。

今回は、令和6年公開問題の科目Bに出題された問4「merge関数の動作」について考えてみよう。
このコードのどこがポイントなのか?」を整理しながら、問題の答えを導き出してみよう。


スポンサーリンク
スポンサーリンク

merge関数の動作を解析する

問題の設定

与えられた関数 merge は、昇順に整列された2つの整数型配列 data1data2 を統合し、新しい昇順配列を作成する。
問題では、次のような呼び出しが行われる。

merge({2, 3}, {1, 4})

ここで、特定の行 /* α */ が何回実行されるかを求める問題だ。

merge関数の処理

この関数は、以下の手順で処理を行う。

  1. work という新しい配列を作成(data1data2 の要素数の合計)
  2. 2つの配列を昇順に併合するため、比較しながら work に格納
  3. どちらかの配列が処理し終わったら、残りの要素をそのまま work に格納

特に注目すべきは、while ループの処理フローだ。

while ((i ≦ n1) and (j ≦ n2))
if (data1[i] ≦ data2[j])
work[k] ← data1[i]
i ← i + 1
else
work[k] ← data2[j]
j ← j + 1
endif
k ← k + 1
endwhile

このループでは、data1data2 の要素を比較し、work に格納していく。
もし data1[i] の方が小さければ data1[i] を、そうでなければ data2[j]work に追加する。

このループが終了した後、data1 または data2 に残った要素を追加する処理が続く。

while (i ≦ n1)
work[k] ← data1[i]
i ← i + 1
k ← k + 1
endwhile

while (j ≦ n2)
work[k] ← data2[j] /* α */
j ← j + 1
k ← k + 1
endwhile

この while (j ≦ n2) の部分で /* α */ の行が実行される回数を求めるのが、この問題のポイントだ。


実際に処理をシミュレーション

では、merge({2, 3}, {1, 4}) の具体的な動きをシミュレーションしてみる。

初期値

data1 = {2, 3} (n1 = 2)
data2 = {1, 4} (n2 = 2)
work = {未定義, 未定義, 未定義, 未定義}
i = 1, j = 1, k = 1

比較ループの実行

  1. 1回目: data1[1] (2)data2[1] (1) を比較

1 の方が小さいため、work[1] = 1
j=2, k=2

  1. 2回目: data1[1] (2)data2[2] (4) を比較

2 の方が小さいため、work[2] = 2
i=2, k=3

  1. 3回目: data1[2] (3)data2[2] (4) を比較

3 の方が小さいため、work[3] = 3
i=3, k=4

この時点で i=3 となり、data1 の全要素が処理されたため、最初の while ループが終了する。


残りの要素を処理

次に data2 に残った要素を work に格納する。

while (j ≦ n2)
work[k] ← data2[j] /* α */
j ← j + 1
k ← k + 1
endwhile

この while ループに入る前の状態は以下の通り。

j = 2, k = 4, n2 = 2

ここで j ≦ n2 は 真 なので、ループを1回実行する。

  1. work[4] = data2[2] (4)
  2. j=3, k=5

ここで j=3 となり、j ≦ n2 は 偽 になるため、ループが終了する。

したがって、/* α */ の行は 1回実行される。

答えは 「イ 1回実行される」 となる。


まとめ

今回の問題は、一見単純な配列の併合処理に見えるが、実際には処理の流れを細かく把握する必要がある。
特に while ループの終了条件や ij の値がどのタイミングで変わるのかを意識すると、コードの動きが明確になる。

基本情報技術者試験の問題を解く上で、こうした逐次的なシミュレーションを行うのは非常に有効だ。
アルゴリズムを暗記するだけでなく、どのように動作するのか をしっかり理解しておくことが、本当の意味での「プログラム理解」につながる。

今後も、試験問題を解く際には「コードを読んで、実際の動きを手でトレースする」ことを意識したい。
配列の処理に苦手意識があるなら、一度じっくり手を動かして、納得できるまでシミュレーションしてみてほしい。

コメント