擬似言語のトレース:戻り値から入力の配列をどう逆算するか
ITパスポート試験 令和6年度 問62 / アルゴリズムとプログラミング › アルゴリズムとプログラミング
過去問にチャレンジ
関数convertは、整数型の配列を一定のルールで文字列に変換するプログラムである。関数convertをconvert(arrayInput)として呼び出したときの戻り値が“AABAB”になる引数arrayInputの値はどれか。ここで、arrayInputの要素数は1以上とし、配列の要素番号は1から始まる。 〔プログラム〕
○文字列型: convert(整数型の配列: arrayInput)
文字列型: stringOutput ← "" // 空文字列を格納
整数型: i
for (iを1からarrayInputの要素数まで1ずつ増やす)
if (arrayInput[i]が1と等しい)
stringOutputの末尾に"A"を追加する
else
stringOutputの末尾に"B"を追加する
endif
endfor
return stringOutput
- ア
{0,0,1,2,1}
- イ
{0,1,2,1,1}
- ウ
{1,0,1,2,0}
- エ
{1,1,2,1,0}
会話形式の解説
講師今回は擬似言語のプログラムを読む問題です。関数が配列の要素を1つずつどう扱っているかをつかめば、計算はほとんどいりません。注目してほしいのは、if文の条件が「1と等しいかどうか」だけだという点です。
受験者for文で要素番号1から順に見ていって、1ならA、そうでなければBを付け足していく処理だと読みました。0と2で何か違いが出るのかが気になっています。
講師読み方は合っています。条件は「1と等しいか」だけなので、0も2も同じくelse側に進み、どちらもBになります。1以外の値はすべてBと考えてかまいません。
受験者それなら、出力の1文字目は1番目の要素、2文字目は2番目の要素というように、順番がそのまま対応しますね。
講師そのとおりです。「末尾に追加する」は文字を後ろにつなげていく操作で、すでにある文字は上書きされません。そこで、求める戻り値“AABAB”から逆にたどってみましょう。どの要素が1でなければならないでしょうか。
受験者Aになっているのは1・2・4文字目なので、1・2・4番目の要素が1で、3番目と5番目は1以外になっている配列を探せばよいはずです。
講師その条件で選択肢を確かめます。{0,0,1,2,1}は1が3番目と5番目にあるので“BBABA”になります。{0,1,2,1,1}は2・4・5番目が1なので“BABAA”です。
受験者{1,0,1,2,0}は1が1番目と3番目だけなので“ABABB”ですね。先頭がAでも、2文字目がBになった時点で条件に合わないと分かります。
講師はい。残る{1,1,2,1,0}は1・2・4番目が1です。念のため順にたどると、i=1で“A”、i=2で“AA”、i=3で“AAB”、i=4で“AABA”、i=5で“AABAB”となり、求める戻り値と一致します。
受験者つまり正解は{1,1,2,1,0}ですね。要素の値が1かどうかだけを見て、出力の文字の位置と要素番号を対応させれば、逆算で選べると理解しました。
講師よくまとまっています。補足すると、この問題は要素番号が1から始まると明記されているので、先頭の要素がi=1に対応します。トレースでは、変数の初期値(ここでは空文字列)と、繰返しごとの変化を表に書き出すと読み違いを防げます。
まとめ
この問題の関数convertは、配列の要素を先頭から順に調べ、1ならA、1以外ならBを文字列の末尾に追加していきます。条件は「1と等しいか」だけなので、0も2もBになります。出力のn文字目は配列のn番目の要素に対応するため、“AABAB”になるのは1・2・4番目が1で、3・5番目が1以外の配列です。この条件を満たすのは{1,1,2,1,0}で、トレースしても戻り値は“AABAB”になります。
解答・解説
正解はエです
この問題のテーマ
擬似言語で書かれた関数convertをトレースし、戻り値が"AABAB"になる入力配列を見つける問題です。配列の各要素が1ならA、1以外ならBに変換するという処理を読み取れるかを確かめます。
解き方の考え方
まず、プログラムが何をするかを確認します。for文で要素番号1から順に要素を1つずつ調べ、1と等しければ"A"を、そうでなければ"B"を、stringOutputの末尾に追加していきます。つまり、出力の何文字目かは、配列の同じ番号の要素に対応します。"AABAB"から逆にたどると、1・2・4番目の要素が1で、3・5番目は1以外でなければなりません。この条件に合う選択肢を探します。
選択肢ごとの解説
- ×ア {0,0,1,2,1}{0,0,1,2,1}の配列を変換すると、B、B、A、B、Aの順に追加され、戻り値は"BBABA"になります。1になっているのは3番目と5番目で、1・2・4番目という条件に合いません。
- ×イ {0,1,2,1,1}{0,1,2,1,1}の配列を変換すると、B、A、B、A、Aの順に追加され、戻り値は"BABAA"になります。1になっているのは2・4・5番目で、1・2・4番目という条件に合いません。
- ×ウ {1,0,1,2,0}{1,0,1,2,0}の配列を変換すると、A、B、A、B、Bの順に追加され、戻り値は"ABABB"になります。1になっているのは1番目と3番目だけで、1・2・4番目という条件に合いません。
- ○エ {1,1,2,1,0}{1,1,2,1,0}の配列では、1になっているのが1・2・4番目なので条件を満たします。トレースすると、i=1で"A"、i=2で"AA"、i=3で"AAB"、i=4で"AABA"、i=5で"AABAB"となり、戻り値は"AABAB"です。問題の求める値と一致します。
補足
条件式は「1と等しいか」だけなので、0も2も含め、1以外の値はすべてelse側に進んでBになります。また、この問題では要素番号が1から始まるので、先頭の要素がi=1に対応します。
POINT
- 関数convertは、配列の要素を先頭から順に調べ、1ならA、1以外ならBを文字列の末尾に追加します。
- 出力のn文字目は配列のn番目の要素に対応するため、求める出力から入力の条件を逆にたどれます。
- 「末尾に追加する」は文字をつなげていく操作で、すでにある文字は上書きされません。
- トレースでは、変数の初期値(ここでは空文字列)と、繰返しごとの変化を順に書き出すと確実です。
