気づけば解けるのは1点 ── いちばん最後の行が返す式と、問題文が決めている戻り値を、ならべて見くらべることです。それだけで、数える係の箱が何を数えているかが決まり、空欄はひとりでに決まります。
難易度 ★★(当サイトの目安)── 「同じ番号どうしを比べて数える」処理だと読み取れれば決まる。4段階の決め方は科目B 最短合格の戦略にあります。
出題
まず原文のまま読んでみてください。記号の読み方は次の節にまとめてありますので、読めない記号があってもここでは問題ありません。
出典:基本情報技術者試験 科目B サンプル問題 問12
次のプログラム中の に入れる正しい答えを,解答群の中から選べ。ここで,配列の要素番号は1 から始まる。
関数simRatio は,引数として与えられた要素数1 以上の二つの文字型の配列s1 とs2 を比較し,要素数が等しい場合は,配列の並びがどの程度似ているかの指標として,(要素番号が同じ要素の文字同士が一致する要素の組みの個数 ÷ s1の要素数)を実数型で返す。例えば,配列の全ての要素が一致する場合の戻り値は1,いずれの要素も一致しない場合の戻り値は0 である。
なお,二つの配列の要素数が等しくない場合は,-1 を返す。
関数simRatio に与えるs1,s2 及び戻り値の例を表に示す。プログラムでは,配列の領域外を参照してはならないものとする。
表 関数simRatio に与えるs1,s2 及び戻り値の例
| s1 | s2 | 戻り値 |
|---|---|---|
{"a", "p", "p", "l", "e"} |
{"a", "p", "p", "l", "e"} |
1 |
{"a", "p", "p", "l", "e"} |
{"a", "p", "r", "i", "l"} |
0.4 |
{"a", "p", "p", "l", "e"} |
{"m", "e", "l", "o", "n"} |
0 |
{"a", "p", "p", "l", "e"} |
{"p", "e", "n"} |
-1 |
〔プログラム〕
○実数型: simRatio(文字型の配列: s1, 文字型の配列: s2)
整数型: i, cnt ← 0
if (s1の要素数 ≠ s2の要素数)
return -1
endif
for (i を 1 から s1の要素数 まで 1 ずつ増やす)
if ( )
cnt ← cnt + 1
endif
endfor
return cnt ÷ s1の要素数 /* 実数として計算する */
解答群
ア s1[i] ≠ s2[cnt] / イ s1[i] ≠ s2[i]
ウ s1[i] = s2[cnt] / エ s1[i] = s2[i]
※ 解答群の原本は ア〜エ を2つの列に分けて並べた形です。当サイトでは2行にまとめて引用しました(字句は変えていません)。
答えだけ先に見る
正解は エ(s1[i] = s2[i])です。
この問題に出てくる記号
読めない記号があったときだけ開いてください。
擬似言語の記号 6コ の読み方をひらく
| 書き方 | 読み方 |
|---|---|
○実数型: simRatio(文字型の配列: s1, 文字型の配列: s2) |
ここから関数 simRatio が始まるという印。文字の配列を2つ受け取って s1・s2 と名前を付け、実数を1つ返します |
整数型: i, cnt ← 0 |
整数の箱を2つ(i と cnt)用意し、cnt に 0 を入れる。← は右の値を左の箱へ入れるという印です |
s1[i] s1の要素数 |
配列 s1 の i 番目の値/s1 に入っている値の個数。要素番号は 1 から始まります |
≠ = |
等しくない/等しい。条件として書かれたときは、成り立てば真、成り立たなければ偽になります |
for (i を 1 から s1の要素数 まで 1 ずつ増やす) |
i を 1, 2, 3 … と s1の要素数 まで変えながら、endfor までをくり返す |
÷ /* … */ |
割り算/注釈。注釈は読む人への説明で、実行には関係ありません。ただし最後の行の「実数として計算する」は、この割り算を小数で計算するという断りです(2 ÷ 5 は 0 ではなく 0.4) |
コードは何をしているか ── 返すのは cnt ÷ s1の要素数
どの行が何をしていそうか、先に見ておきます。
○実数型: simRatio(文字型の配列: s1, 文字型の配列: s2)
文字の配列を2つ受け取り、実数を1つ返す
整数型: i, cnt ← 0
数える係の cnt を0 から始める
if (s1の要素数 ≠ s2の要素数)
2つの配列の要素数が違うとき
return -1
-1 を返して、ここで終わり。表のいちばん下、s2 が {"p", "e", "n"} の行がこれ
endif
枝分かれの終わり
for (i を 1 から s1の要素数 まで 1 ずつ増やす)
要素番号 i を 1 から最後まで動かす
if ( )
ここが空欄。この条件が真のときだけ、すぐ下の行へ入る
cnt ← cnt + 1
cnt を1増やす。この行を通った回数が、そのまま cnt の値になる
endif
枝分かれの終わり
endfor
くり返しの終わり
return cnt ÷ s1の要素数 /* 実数として計算する */
返すのはこの式。割る数は決まっているので、cnt が決まれば戻り値も決まる
※ 右側の注釈は当サイトで書き加えたものです。プログラム自体は原文のまま引用しています。
空欄の中身はまだ分かりませんが、まわりの行だけで言えることがあります。cnt は 0 から始まり、増える行は cnt ← cnt + 1 の1か所だけ。その行に入るのは空欄の条件が真だった回だけです。つまり cnt は、空欄の条件が真になった回数です。
そして最後の行が返すのは cnt ÷ s1の要素数。問題文は戻り値を「(要素番号が同じ要素の文字同士が一致する要素の組みの個数 ÷ s1の要素数)」と決めています。割る数がどちらも s1の要素数 でそろっているので、割られる数の cnt は「要素番号が同じ要素の文字同士が一致する要素の組みの個数」でなければなりません。
空欄に入るものを決める ── 一致した組を、要素番号をそろえて数える
〔プログラム〕空欄のまわり
for (i を 1 から s1の要素数 まで 1 ずつ増やす)
if ( )
cnt ← cnt + 1
endif
endfor
※ 上の〔プログラム〕からの抜粋です(1字も変えていません)。
決めることは2つ。どの2つを比べるのかと、どちらのときに cnt を増やすのかです。表の2行目(戻り値 0.4)の例で見ます。
同じ要素番号どうしを、縦にならべて見くらべる
緑=文字が一致している組/赤=一致していない組
表の2行目の s1 と s2
s1
1“a”
2“p”
3“p”
4“l”
5“e”
s2
1“a”
2“p”
3“r”
4“i”
5“l”
問題文が言う「要素番号が同じ要素の文字同士」は、1番と1番、2番と2番、…のこと。一致しているのは2組だけです(4番は小文字のエル "l" と "i")。
くらべる2つは、どちらも同じ要素番号 i で取り出す。
cnt は条件が真になった回数であり、前の節で決めたとおり一致した組の個数でもあります。つまり条件は、一致したときだけ真になればよい。比べる2つはどちらも同じ要素番号 i、真になるのは等しいときです。
解答群を見る
s1[i] = s2[i] ── エ です。
答え合わせ
正解は エ です。
エなら表の4行が全部そろいます(5 ÷ 5 = 1/2 ÷ 5 = 0.4/0 ÷ 5 = 0/4行目は要素数がちがうので return -1)。2行目の例を最後まで動かして確かめます。
1行ずつ追う 正解の エ で simRatio({"a", "p", "p", "l", "e"}, {"a", "p", "r", "i", "l"})
出典:科目B サンプル問題 問12(空欄に エ を入れたもの)
ループ開始前
配列
いま計算していること
変数の状態
return で返した値
トレース表(進めると1行ずつ積み上がります)
次に読む
この問題でどこに手間取ったかで、行き先が変わります。
i を 1 から動かして全部見る形がつかめなかった人へ問10サンプル問題 問10 ── 単方向リストから1つ削除する回です一覧科目B 全44問の解説 ── 続けて解きたい人へこの記事で引用した資料
いずれも独立行政法人情報処理推進機構(IPA)が公表したものです。IPAは公表済みの試験問題について、教育目的での使用に許諾および使用料を不要としていますが、著作権は放棄していません。本記事では問題文を改変せずに引用しています。

