令和8年度の科目B、その5問目です。くり返しの中にくり返しが入っていて、番号が i j k と3つ出てきます。ここでいちばん大事なのは、このプログラムが2つの仕事に分かれていると気づくことです。分けてしまえば、あとは片方ずつ読めば済みます。
出題
まず原文のまま読んでみてください。本番で最初に見るのは、この見た目そのものです。解説を読んだあとで戻ってくる場所でもあるので、いま読めなくてもかまいません(記号の読み方は次の節にまとめてあります)。
出典:令和8年度 基本情報技術者試験 科目B 公開問題 問5
次のプログラム中の a と b に入れる正しい答えの組合せを,解答群の中から選べ。ここで,配列の要素番号は1 から始まる。
一つの要素だけが1 で他の要素が0 であるような整数型の配列による表現を,本問ではOne-Hot 表現という。関数oneHotEncoding は,図のように,色の名前が格納されている要素数1 以上の文字列型の配列を引数として受け取り,配列に含まれる色の名前(図の例では3 種類)に基づいて,各要素をOne-Hot 表現に変換し,整数型配列の配列に格納して返す。関数oneHotEncoding における変換の例を図に示す。
引数の例: {“Red”, “Green”, “Blue”, “Red”}
↓
“Red”のOne-Hot 表現 : {1, 0, 0}
“Green”のOne-Hot 表現: {0, 1, 0}
“Blue”のOne-Hot 表現 : {0, 0, 1}
↓
引数の例に対応する戻り値: {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}, {1, 0, 0}}
図 関数oneHotEncoding における変換の例
〔プログラム〕
○整数型配列の配列: oneHotEncoding(文字列型の配列: colors)
整数型: i, j, k
文字列型の配列: colorVector ← {} // 要素数0の配列
整数型の配列: tempVector
整数型配列の配列: oneHotVector ← {} // 要素数0の配列
/* 名前一覧の作成 */
for (i を 1 から colorsの要素数 まで 1 ずつ増やす)
if (colorVector の要素のいずれにも colors[i]の値 が格納されていない)
colorVectorの末尾 に a を追加する
endif
endfor
/* One-Hot表現への変換 */
for (j を 1 から colorsの要素数 まで 1 ずつ増やす)
tempVector ← {} // 要素数0の配列
for (k を 1 から colorVectorの要素数 まで 1 ずつ増やす)
if (b)
tempVectorの末尾 に 1 を追加する
else
tempVectorの末尾 に 0 を追加する
endif
endfor
oneHotVectorの末尾 に tempVector を追加する
endfor
return oneHotVector
解答群
ア a:colors[i]の値 b:colors の要素のいずれかに colorVector[k]の値 が格納されている
イ a:colors[i]の値 b:colors[j] が colorVector[k] と等しい
ウ a:未定義の値 b:colors の要素のいずれかに colorVector[k]の値 が格納されている
エ a:未定義の値 b:colors[j] が colorVector[k] と等しい
答えだけ先に見る
正解は イ です。なぜイになるのかは、この記事で2手に分けて絞ります。
この問題に出てくる記号
読めない記号があったときだけ開いてください。先に全部読む必要はありません。
擬似言語の記号 14コ の読み方をひらく
| 書き方 | 読み方 |
|---|---|
○整数型配列の配列:oneHotEncoding(文字列型の配列: colors)return ◯ |
○ はここから関数が1つ始まるという印。関数=ひとまとまりの処理につけた名前です。○ のうしろが返すものの型、括弧の中が受け取るものの型と名前(これを引数といいます)。return ◯ で ◯ を返して、その関数はそこで終わります。返したものを「戻り値」といいます。関数は外から呼ばれて動き出します(この問題では、誰かが oneHotEncoding({"Red", …}) と呼ぶところから始まります) |
colorVector ← {} |
右の値を、左へ入れる。この例なら「colorVector を空の配列にする」。入れられた側(左)は前の中身が消えて上書きされます |
colors[i]colors[i]の値 |
配列 colors の i 番目の箱。角かっこの中を添字といい、数字のほかに i のような箱の名前も書けます(i に 2 が入っていれば colors[2] のこと)。「の値」は「その箱の中身」という念押しで、指しているものは同じです |
整数型文字列型 |
その箱に何を入れるかの決まり。整数型 なら整数だけ、文字列型 なら文字の並びだけが入ります |
"Red" |
文字の並びは二重引用符でくくって書きます。"Red" と "Green" は別のもの、"Red" と "Red" は等しい |
整数型の配列整数型配列の配列 |
前者は {1, 0, 0} のような1行ぶん。後者はその1行ぶんを要素にした配列で、{{1, 0, 0}, {0, 1, 0}} のように2行ぶん入ります |
未定義の値 |
中身が何も無いことを表す書き方。色の名前でも数でもありません |
{} |
要素が1つも入っていない配列。{1, 0, 0} なら3つ入った配列です |
◯の要素数 |
その配列に入っている個数。{"Red", "Green", "Blue", "Red"} なら 4 です |
◯の末尾 に ◯ を追加する |
配列を1つ伸ばして、いちばん後ろに置く。{1} の末尾に 0 を追加すると {1, 0} になります |
for (…)endfor |
あいだの行を何度もくり返す。くり返しの1回ぶんを、この記事では「1周」と呼びます。for の中に、もう1つ for を書くこともできます(二重ループ。中と外の関係を入れ子といいます) |
if (…)elseendif |
かっこの中が成り立てば if の下、成り立たなければ else の下を実行します。どちらか一方だけが動きます |
◯ の要素のいずれにも |
その配列のどこを探しても見つからない、という意味。配列が空(要素数0)のときも成り立ちます ── 探す相手が1つも無いので、当然見つかりません。「いずれかに格納されている」はその反対で、どこかに1つでもあれば成り立ちます |
/* … */// … |
どちらもコメント。人が読むための書き込みで、実行されません。// のほうは行の終わりまでがコメントです |
これで手が止まるところがあれば、下の教科書から先にそこだけ拾ってきてください(G9-2 のような番号は、当サイトの擬似言語の教科書の第何回かを表します)。
for の中に for があると、内側は何回まわるかG5選択処理 if ─ else が実行されるのはどんなときかG4配列 ─ {} の書き方と、末尾に追加するという操作G2-2型 ─ 文字列型と整数型のちがいOne-Hot 表現とは、どういう並びか
問題文の定義はこうです。「一つの要素だけが1 で他の要素が0 であるような整数型の配列による表現」。言い換えると、種類の数だけ箱を並べて、当たった1つだけに 1 を立てるやり方です。
図の例では色が 3種類(Red・Green・Blue)なので、箱は 3つ。何番目の箱が Red なのかは、この3種類を並べた順で決まります。
この記事では、配列の1つぶんの入れ物を箱、その位置を桁と呼びます。あとで出てくる画面の枡も同じものです。
“Red” の One-Hot 表現
“Green” の One-Hot 表現
“Blue” の One-Hot 表現
ここで決まる2つのこと
桁数 = 並べた一覧の長さ(この例では 3)
何番目に 1 が立つか = その色が、種類の一覧で何番目か
だからプログラムは、まず「出てきた色の一覧」を作るところから始めます。一覧ができるまで、箱がいくつ要るのかも決まりません。その一覧に何をどう入れるかは、次の節から見ていきます。
前半で一覧を作り、後半で見比べる
番号が i j k と3つ出てきますが、前半の i と、後半の j・k が同時に動くことはありません。プログラムは前半と後半に分かれていて、原文のコメントがその切れ目を教えてくれています。
| やること | 動く番号 | できあがるもの | |
|---|---|---|---|
前半/* 名前一覧の作成 */ |
受け取った色を先頭から見て、まだ一覧に無い色だけを一覧に足す(何を足すかを書く場所が空欄a) | i |
colorVector(色の一覧) |
後半/* One-Hot表現への変換 */ |
受け取った色をもう一度先頭から見て、1色ずつ 0と1 の並びを作る | j と k(for が入れ子になっていて、j が外側、k が内側) |
oneHotVector(答え) |
空欄は前半に1つ・後半に1つです。ここでは空欄をいったん脇に置いて、引数の例 {"Red", "Green", "Blue", "Red"} を自分の手で1回通します。ここで手にするものが、そのまま空欄の答えになります。
前半 ── 初めて見た色だけを、一覧に足す
if の条件は「一覧のどこにも入っていない」。つまり初めて見た色のときだけ足す、ということです。先頭から順に見ていきます。
一覧 colorVector のでき方
1つ目 "Red" … 一覧は空。無いので足す → {"Red"}
2つ目 "Green" … 無いので足す → {"Red", "Green"}
3つ目 "Blue" … 無いので足す → {"Red", "Green", "Blue"}
4つ目 "Red" … もうあるので足さない → {"Red", "Green", "Blue"}
できあがった一覧は 3個。並ぶ順は受け取った順(末尾に足していくだけなので、先に来た色が先頭に来ます)。渡した色は4つですが、一覧に並ぶのは種類だけで、その個数がそのまま One-Hot の桁数になります。
後半 ── いま変換している色を、一覧と1つずつ見比べる
後半は、変換したい色を1つ決めて、一覧を先頭から見比べるだけです。2色目の "Green" でやってみます。
2色目 "Green" を変換する
一覧の1番目は "Red" … ちがう → 1桁目に 0
一覧の2番目は "Green" … 同じ → 2桁目に 1
一覧の3番目は "Blue" … ちがう → 3桁目に 0
できたのは {0, 1, 0}。問題の図の "Green"のOne-Hot 表現 と一致します。見比べた一覧の番号が、そのまま桁の番号です。
あとは、これを受け取った色の数だけくり返すだけです。渡した4色ぶん積み上げれば、問題の図の戻り値ができあがります。
コードの中で、a は「一覧に並べるもの」、b は「1 を置く条件」
いま手でやったことを、プログラムはどう書いているのか。注釈を付けて見ます。
○整数型配列の配列: oneHotEncoding(文字列型の配列: colors)
色の名前の配列を受け取り、0と1の配列を並べて返す
整数型: i, j, k
3つとも、くり返しが動かす番号
文字列型の配列: colorVector ← {} // 要素数0の配列
出てきた色の一覧。はじめは空
整数型の配列: tempVector
1色ぶんの 0と1 を入れる箱。中身は後半で入れる
整数型配列の配列: oneHotVector ← {} // 要素数0の配列
答え。tempVector をここへ積んでいく
/* 名前一覧の作成 */
前半 ── ここから
for (i を 1 から colorsの要素数 まで 1 ずつ増やす)
受け取った色を先頭から1つずつ見る
if (colorVector の要素のいずれにも colors[i]の値 が格納されていない)
この色を一覧に足すかどうかを、ここで決める
colorVectorの末尾 に a を追加する
空欄a ── 一覧に何を足すか
endif
endfor
前半 ── ここまで。一覧ができあがる
/* One-Hot表現への変換 */
後半 ── ここから
for (j を 1 から colorsの要素数 まで 1 ずつ増やす)
受け取った色を、もう一度先頭から1つずつ
tempVector ← {} // 要素数0の配列
この色ぶんの箱を空にする
for (k を 1 から colorVectorの要素数 まで 1 ずつ増やす)
一覧を先頭から見る。一覧の要素数だけくり返す
if (b)
空欄b ── 1 を置くか 0 を置くかの判定
tempVectorの末尾 に 1 を追加する
当たり
else
そうでなければ
tempVectorの末尾 に 0 を追加する
はずれ
endif
endfor
1色ぶんの並びができた
oneHotVectorの末尾 に tempVector を追加する
答えに1行積む
endfor
return oneHotVector
並べ終わったものを返す
※ 右側の注釈は当サイトで書き加えたものです。プログラム自体は原文のまま引用しています。
番号が2つあるのは、いまの手作業が二重になっているからです。外側の j がいま何色目を変換しているか、内側の k が一覧の何番目と見比べているか。j が1つ進むごとに tempVector ← {} で作りかけの箱が空に戻り、k はまた 1 から回り直します。
この2つの for が、答えの形を決める
行数 = 外側の上限 colorsの要素数(4) … 1色につき1行
桁数 = 内側の上限 colorVectorの要素数(3) … 1桁ずつ末尾に積む
4色ぶん積んで 4行 × 3桁 ── 問題の図の戻り値 {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}, {1, 0, 0}} の形です。
空欄に入るものを決める
解答群を先に見ると、似た式が4つ並んでいて迷います。入れるべきものを自分で決めてから、最後に照合するほうが速いです。どちらの空欄も、さっき手でやったことがそのまま答えになります。
先に決めるのは後半の b のほうです。前半の a(一覧に何を並べるか)は、その一覧が後半で何と見比べられるかが決まって初めて、入れるべきものが決まるからです。
空欄 b ── if (b) は「この桁を 1 にするか」を決める行
2色目を変換したとき、何と何を見比べましたか。「いま変換している色」と「一覧の k 番目」です。前者はプログラムでは colors[j]、後者は colorVector[k]。この2つが等しいときだけ 1 を置く ── それがこの行の仕事です。決めるのは、後半のこの行です。
〔プログラム〕空欄b のある内側のくり返し
for (k を 1 から colorVectorの要素数 まで 1 ずつ増やす)
if (b)
tempVectorの末尾 に 1 を追加する
else
tempVectorの末尾 に 0 を追加する
※ 上の〔プログラム〕からの抜粋です(1字も変えていません)。
空欄b が決めるのは、その桁を 1 にするか 0 にするか
※ 枡の上の数字は要素番号です。
2色目を変換しているところ(j = 2 なので colors[j] は "Green")
いま変換している色colors[j]
2“Green”
等しい
一覧colorVector[k]
1“Red”
2“Green”
3“Blue”
できる桁tempVector
10
21
30
見比べる相手は、いつも colors[j] ひとつ。矢印のとおり、これを一覧の1番目から3番目まで順に当てて、等しかった桁にだけ 1、ちがった桁には 0 を置きます。
条件に j が無いと、この矢印の出どころが色ごとに変わりません ── どの色を変換しても、まったく同じ並びができてしまいます。問題の図は1色目と2色目で別の並びなので、それでは作れません。
b に入るもの
if (colors[j] が colorVector[k] と等しい)
空欄 a ── colorVectorの末尾 に a を追加する は「一覧に何を並べるか」を決める行
手で作った一覧は {"Red", "Green", "Blue"} ── 色の名前そのものでした。プログラムで、いま見ている色の名前を指しているのは colors[i]の値 です。ここが色の名前でないと、桁数と中身が同時に壊れます。決めるのは、前半のこの行です。
〔プログラム〕空欄a のある前半
for (i を 1 から colorsの要素数 まで 1 ずつ増やす)
if (colorVector の要素のいずれにも colors[i]の値 が格納されていない)
colorVectorの末尾 に a を追加する
※ 上の〔プログラム〕からの抜粋です(1字も変えていません)。
空欄a に何を入れるかで、一覧の中身と長さが変わる
colors[i]の値(色の名前)を足した場合
一覧 colorVector
1“Red”
2“Green”
3“Blue”
3個 = 3桁。中身は色の名前なので、colors[j] と等しくなる桁がある。
未定義の値 を足した場合
一覧 colorVector
1未定義
2未定義
3未定義
4未定義
4個 = 4桁にずれる(一覧に色が入らないので、if が4回とも成り立って全部足される)。しかも色の名前と等しくなることが無いので、どの桁も 0 のまま。
問題の図の One-Hot は 3桁でした。
a に入るもの
colorVectorの末尾 に colors[i]の値 を追加する
ここで初めて解答群を見る
a が colors[i]の値、b が colors[j] が colorVector[k] と等しい。解答群でこの組合せは イ ひとつだけです。
本番の手順 ── 条件の中に「動いている番号」が入っているかを見る
- くり返しの中の
ifを見たら、その条件にくり返しの番号が入っているかを確かめる。入っていなければ、1周進んでも判定はまったく変わりません。行ごとに違うものを作りたい処理なら、そこが誤りです。 - 二重ループなら、どちらの番号が入っているかまで見る。外側と内側の両方が条件に効いているのがふつうです。片方しか出てこなければ、そこが疑い所。
- 配列に何かを足す行は、その中身があとで何と見比べられるかから決める。足したものと見比べる相手が同じ種類のものでなければ、判定は一度も成り立ちません。この問題なら、見比べる相手は色の名前なので、足すのも色の名前です。ここまでは読むだけで済み、1桁ずつ数えるのは最後の確認だけで足ります。
答え合わせ ── 入れて動かすと問題の図の戻り値が出る
空欄に イ を入れて、{"Red", "Green", "Blue", "Red"} を最後まで通します。見るのは 一覧 colorVector・作りかけ tempVector・答え oneHotVector の3つの欄です。
1行ずつ追う 正解の イ
出典:令和8年度 科目B 公開問題 問5(空欄に イ を入れたもの)
ループ開始前
colors と、作りかけの一覧・並び
いま計算していること
変数の状態
return で返すもの
トレース表(進めると1行ずつ積み上がります)
正解は イ
a に colors[i]の値、b に colors[j] が colorVector[k] と等しい。一覧には色の名前そのものを並べ、変換では「いま変換している色」と「一覧の k番目」を突き合わせる ── これで、当たった1つの桁だけに 1 が立ちます。
ほかの3つを入れるとこうなります。ア=条件に j が無く、しかも一覧の色は colors に必ずあるので判定がいつも成り立ち、4行とも {1, 1, 1}。ウ・エ=一覧が 未定義 4個になり、どちらも {0, 0, 0, 0} が4行。ウ と エ は戻り値が同じです ── 空欄a が壊れていると、空欄b のちがいが結果に出てきません。
同じ考え方で解く練習問題
身についたかどうかは、渡すものを変えた問題で確かめるのがいちばんです。プログラムは空欄を埋めた正解の形から1文字も変えていません ── 変えたのは渡す色だけです。桁数がいくつになるかを、自分で決めてみてください。
当サイトで作った類題です
次の決まりで動く関数に、colors = {“Blue”, “Blue”, “Red”}(要素数3)を渡します。戻り値はどれですか。
○整数型配列の配列: oneHotEncoding(文字列型の配列: colors)
整数型: i, j, k
文字列型の配列: colorVector ← {} // 要素数0の配列
整数型の配列: tempVector
整数型配列の配列: oneHotVector ← {} // 要素数0の配列
/* 名前一覧の作成 */
for (i を 1 から colorsの要素数 まで 1 ずつ増やす)
if (colorVector の要素のいずれにも colors[i]の値 が格納されていない)
colorVectorの末尾 に colors[i]の値 を追加する
endif
endfor
/* One-Hot表現への変換 */
for (j を 1 から colorsの要素数 まで 1 ずつ増やす)
tempVector ← {} // 要素数0の配列
for (k を 1 から colorVectorの要素数 まで 1 ずつ増やす)
if (colors[j] が colorVector[k] と等しい)
tempVectorの末尾 に 1 を追加する
else
tempVectorの末尾 に 0 を追加する
endif
endfor
oneHotVectorの末尾 に tempVector を追加する
endfor
return oneHotVector
※ {} の中はいちばん左が1番目です。
「一覧と見比べる」問題を見分ける
この形は、前半で一覧を作り、後半でその一覧と見比べるという2段構えが合図です。見つけたら、次の順で読みます。
| 見るところ | 読み取ること |
|---|---|
| コメントや空行の切れ目 | そこが段の変わり目。前半が終わってから後半が始まるので、i が動いている間は j も k も動きません。後半の j と k は入れ子で、内側の k が 1 から最後まで一巡するあいだ、外側の j は止まったままです |
内側の for の上限が、どちらの配列を指しているか |
指しているのが一覧のほうなら正しい(作られる並びの長さになります)。元の配列のほうを指していたら、そこが誤りの候補です |
| 「いずれにも〜ない」か「いずれかに〜ある」か | 否定か肯定かで意味が正反対になります。同じものを2回足さないために使うのは前者です |
次に読む
この問題でどこに手間取ったかで、行き先が変わります。
else の範囲が曖昧だった人へ一覧公開されている科目B 44問の解説 ── 同じ形の問題を続けて解きたい人へこの記事で引用した資料
いずれも独立行政法人情報処理推進機構(IPA)が公表したものです。IPAは公表済みの試験問題について、教育目的での使用に許諾および使用料を不要としていますが、著作権は放棄していません。本記事では問題文を改変せずに引用しています。
「{“Blue”, “Blue”, “Red”} を通す練習問題」は当サイトのオリジナルです。

