令和8年度 基本情報技術者試験 科目B 問5の解説|One-Hot 表現に変換する

基本情報技術者試験

令和8年度 科目B 公開問題 問5擬似言語・二重ループ・文字列の配列最終更新 2026-09-04

令和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 (…)
else
endif
かっこの中が成り立てば if の下、成り立たなければ else の下を実行します。どちらか一方だけが動きます
◯ の要素のいずれにも
◯ が格納されていない
その配列のどこを探しても見つからない、という意味。配列が空(要素数0)のときも成り立ちます ── 探す相手が1つも無いので、当然見つかりません。「いずれかに格納されている」はその反対で、どこかに1つでもあれば成り立ちます
/* … */
// …
どちらもコメント。人が読むための書き込みで、実行されません。// のほうは行の終わりまでがコメントです

これで手が止まるところがあれば、下の教科書から先にそこだけ拾ってきてください(G9-2 のような番号は、当サイトの擬似言語の教科書の第何回かを表します)。

One-Hot 表現とは、どういう並びか

問題文の定義はこうです。「一つの要素だけが1 で他の要素が0 であるような整数型の配列による表現」。言い換えると、種類の数だけ箱を並べて、当たった1つだけに 1 を立てるやり方です。

図の例では色が 3種類(Red・Green・Blue)なので、箱は 3つ。何番目の箱が Red なのかは、この3種類を並べた順で決まります。

この記事では、配列の1つぶんの入れ物を箱、その位置を桁と呼びます。あとで出てくる画面の枡も同じものです。

“Red” の One-Hot 表現

11
20
30

“Green” の One-Hot 表現

10
21
30

“Blue” の One-Hot 表現

10
20
31

ここで決まる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] と等しい。解答群でこの組合せは イ ひとつだけです。

本番の手順 ── 条件の中に「動いている番号」が入っているかを見る

  1. くり返しの中の if を見たら、その条件にくり返しの番号が入っているかを確かめる。入っていなければ、1周進んでも判定はまったく変わりません。行ごとに違うものを作りたい処理なら、そこが誤りです。
  2. 二重ループなら、どちらの番号が入っているかまで見る。外側と内側の両方が条件に効いているのがふつうです。片方しか出てこなければ、そこが疑い所。
  3. 配列に何かを足す行は、その中身があとで何と見比べられるかから決める。足したものと見比べる相手が同じ種類のものでなければ、判定は一度も成り立ちません。この問題なら、見比べる相手は色の名前なので、足すのも色の名前です。ここまでは読むだけで済み、1桁ずつ数えるのは最後の確認だけで足ります。

答え合わせ ── 入れて動かすと問題の図の戻り値が出る

空欄に イ を入れて、{"Red", "Green", "Blue", "Red"} を最後まで通します。見るのは 一覧 colorVector・作りかけ tempVector・答え oneHotVector の3つの欄です。

1行ずつ追う 正解の イ

出典:令和8年度 科目B 公開問題 問5(空欄に イ を入れたもの)


ループ開始前

colors と、作りかけの一覧・並び

▲ いま読んでいる▲ いま書いた

いま計算していること

まだ計算していません

変数の状態

トレース表(進めると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回足さないために使うのは前者です

次に読む

この問題でどこに手間取ったかで、行き先が変わります。

この記事で引用した資料

いずれも独立行政法人情報処理推進機構(IPA)が公表したものです。IPAは公表済みの試験問題について、教育目的での使用に許諾および使用料を不要としていますが、著作権は放棄していません。本記事では問題文を改変せずに引用しています。

「{“Blue”, “Blue”, “Red”} を通す練習問題」は当サイトのオリジナルです。

Copied title and URL