令和6年度 基本情報技術者試験 科目B 問2の解説|2進数の文字列を整数にする

基本情報技術者試験

令和6年度 科目B 公開問題 問2擬似言語・文字列・繰返し・2進数最終更新 2026-09-04

令和6年度の科目B、その2問目です。“10010” という文字の並びを、18 という数にする関数を読みます。空欄は1つだけ。ただしそこには 「なぜ2倍するのか」が入っていて、そこが分からないまま解答群を眺めると、4つとも同じに見えます。この記事では、2倍する理由を自分で作れるところまで進みます。

出題

まず原文のまま読んでみてください。記号の読み方は次の節にまとめてありますので、読めなくてもここでは問題ありません。

出典:令和6年度 基本情報技術者試験 科目B 公開問題 問2

次のプログラム中の   に入れる正しい答えを,解答群の中から選べ。

関数convDecimal は,引数として与えられた,“0”と“1”だけから成る,1 文字以上の文字列を,符号なしの2 進数と解釈したときの整数値を返す。例えば,引数として“10010”を与えると18 が返る。

関数convDecimal が利用する関数int は,引数で与えられた文字が“0”なら整数値0 を返し,“1”なら整数値1 を返す。

〔プログラム〕

○整数型: convDecimal(文字列型: binary)
  整数型: i, length, result ← 0
  length ← binaryの文字数
  for (i を 1 から length まで 1 ずつ増やす)
    result ←  
  endfor
  return result

解答群

ア result + int(binary の (length - i + 1)文字目の文字)

イ result + int(binary の i文字目の文字)

ウ result × 2 + int(binary の (length - i + 1)文字目の文字)

エ result × 2 + int(binary の i文字目の文字)

答えだけ先に見る

正解は エ(result × 2 + int(binary の i文字目の文字))です。2倍がなぜ要るのか、なぜ左から読むのかを、この記事では順に作ります。

この問題に出てくる記号

読めない記号があったときだけ開いてください。いま読めればいいのは9つだけで、細かいところは使う場面で足していきます。

擬似言語の記号 9コ の読み方をひらく
書き方 読み方
○整数型: convDecimal(…) ここから関数が1つ始まるという印。○ のうしろの 整数型 は返すものの型、括弧の中が受け取るものです
文字列型: binary binary という箱に文字の並びが入る、ということ。"10010" のように、1文字ずつが順に並んでいます
整数型: i, length, result ← 0 箱を3つ用意します。← が付いているのは result のほうなので、0 が入るのは result だけです
a ← b 右の値を、左へ入れる。左は前の中身が消えて上書きされます。右はそのままです
binaryの文字数 その文字列に何文字あるか。"10010" なら 5 です
binary の (length - i + 1)文字目の文字 かっこの中を先に計算して、その番号の文字を取り出します。length = 5、i = 1 なら 5 - 1 + 1 = 5 で5文字目。この式を選ぶかどうかは、あとの節で決めます
binary の i文字目の文字 左から数えて i 番目の1文字。i が 1 なら左端です
int(…) 関数を呼ぶ書き方。括弧の中を渡すと、答えが返ってきます。この int は文字を数に変えるもので、"0" なら 0、"1" なら 1 を返します
for (…)
endfor
あいだの行を何度もくり返す。i を 1 から 5 まで 1 ずつ増やす なら、i が 1, 2, 3, 4, 5 と変わりながら5回実行されます。くり返しの1回ぶんを、この記事では「1周」と呼びます
× + かけ算と足し算。× のほうが先に計算されますので、a × 2 + b は (a × 2) + b という意味です

記号でつまずいたら、下の教科書から、先にそこだけ読んでください(G6-1 のような番号は、当サイトの擬似言語の教科書の第何回かを表します)。

“10010” が 18 になる仕組み(一般的な計算方法)

まず、この関数が何をするのかをプログラム抜きで確かめます(出題の「符号なし」はマイナスの数は考えない、という意味です)。

2進数は、右端から 1, 2, 4, 8, 16 … と、左へ行くほど2倍ずつ重くなる並びです。

“10010” を、重みを使って数える

上の段が出題の文字、下の段がその桁の重みです。琥珀=いま注目している桁(文字が 1)/灰=足さない桁。「次へ」で1手ずつ進みます。

① 枡の下に、その桁の重みを並べる

文字

11

20

30

41

50

重み

116

28

34

42

51

重みは右端が 1で、左へ行くほど2倍ずつ(1 → 2 → 4 → 8 → 16)。上下は同じ位置どうしが組です。

② 文字が 1 の桁だけ残す

文字

11

20

30

41

50

重み

116

28

34

42

51

残るのは 1つ目(重み 16)と 4つ目(重み 2)。文字が 0 の桁は、いくつを掛けても 0 なので足しません。

③ 残った重みを足す

足す重み

1つ目16

4つ目2

16 + 2 = 18。出題の「引数として“10010”を与えると18 が返る」と合いました。

文字が 1 の桁の重みだけを足す ── 16 + 2 = 18

ここで、数えた向きに注目してください。重みを使う計算は、右端から始まります。1, 2, 4, 8, 16 と、右から順に決まっていくからです。

ところが、プログラムは左から読む

出題の for は i を 1 から 増やします。i 文字目は左から数えた番号なので、このプログラムは左端から順に読んでいくことになります ── いま数えたのと、ちょうど逆向きです。

つまり、この問題で考えることは1つです。

この問題の勘所

重みを使わず、左から1文字ずつ読むだけで、同じ 18 にたどり着くには?

左から読んで、同じ答えにたどり着くには

まず10進数で考えます。1、2、3 と左から読んでいくとき、手もとの数はこう育ちます。

読んだ文字 手もとの数はどうなるか 計算 手もとの数
(はじめ) まだ何もない — 0
1 0 の右に 1 を書く → 1 0 × 10 + 1 1
2 1 の右に 2 を書く → 12 1 × 10 + 2 12
3 12 の右に 3 を書く → 123 12 × 10 + 3 123

右に1文字書くと、それまでの数はひと桁ぶん左へ押し出されます。1 は一の位から十の位へ、12 は十と一の位から百と十の位へ。だから10倍して、空いた一の位に読んだ文字を入れる ── それが 12 × 10 + 3 です。

2進数でも、やることは同じ。10倍が2倍になるだけです。

1文字読むたびにやること

いまの result を2倍して、読んだ文字(0 か 1)を足す。

"10010" で、5文字ぶん実際にやってみます。2進数の桁は、もう出てきません ── ふつうの足し算とかけ算だけです。

何文字目 読んだ文字 計算 result
(はじめ) — — 0
1文字目 1 0 × 2 + 1 1
2文字目 0 1 × 2 + 0 2
3文字目 0 2 × 2 + 0 4
4文字目 1 4 × 2 + 1 9
5文字目 0 9 × 2 + 0 18

18。前の節で重みを足して出した 16 + 2 = 18 と同じ数になりました。右から重みを掛けなくても、左から読むだけで同じところへ着きます。

コードの中で、空欄は「1周ぶん進めた result」を作る行

いま手でやったことを、プログラムの各行に当てはめます。for のくり返し1回ぶんを、この記事では「1周」と呼びます。

○整数型: convDecimal(文字列型: binary)

 

整数型: i, length, result ← 0

 

length ← binaryの文字数

"10010" なら 5。これがくり返す回数になる

for (i を 1 から length まで 1 ずつ増やす)

i が 1, 2, 3, 4, 5 と変わりながら5回くり返す

result ←  

ここが空欄。1周ぶん進めた新しい result を作る行

endfor

for の行へ戻り、i が1増えてもう1周する

return result

育てた result を返す=呼んだ側へ渡して終わり

※ 右側の注釈は当サイトで書き加えたものです。プログラム自体は原文のまま引用しています。

result がこのプログラムの主役

result は「ここまで読んだぶんの値」。出発点は 0 で、1周ごとに result を作り直すことが「1文字読む」ことにあたります。

空欄に入るものを決める

決めるのは、この行です。

〔プログラム〕空欄のある行と、それを囲むくり返し

  for (i を 1 から length まで 1 ずつ増やす)
    result ←  
  endfor

※ 上の〔プログラム〕からの抜粋です(1字も変えていません)。

入るのは新しい result。前の節で書き出したとおり、それはいまの result を2倍して、いま読んだ文字の値を足したものです。文字を 0 か 1 の数に変えるのが int(…) でした。

ここまでで決まったこと

result × 2 + int( いま読んだ文字 )

残るは「いま読んだ文字」をどう書くかだけです。for は i を 1 から length まで増やすので、i をそのまま文字の番号に使えば、左から順に読めます。

i = 1 のとき、どの文字を読むか

どちらも i = 1(くり返しの1周目)のときです。琥珀が、その周で読む文字。

i 文字目 と書いた場合

11

20

30

41

50

i = 1 なので 1文字目。i が増えるほど右へ進むので、左から順に読みます。

(length - i + 1) 文字目 と書いた場合

11

20

30

41

50

length = 5 なので 5 - 1 + 1 = 5、つまり 5文字目。i が増えるほど左へ戻るので、右から順に読みます。

左から読みたいので、書くのは i 文字目。

空欄に入るもの

result ← result × 2 + int(binary の i文字目の文字)

× は + より先に計算されますので、かっこは要りません((result × 2) + int(…) と同じ意味です)。

ここで初めて解答群を見る

result × 2 + int(binary の i文字目の文字)。解答群でこの式は エ ひとつだけです。

本番の手順 ── くり返しの中の ◯ ← ◯ … は、手で2〜3周ぶん作って決める

  1. その箱が覚えているものを、名前ではなく中身で言う。ここでは result =「ここまで読んだぶんの値」。これが決まらないと、次に進めません。
  2. 2〜3周ぶんを手で並べて、前の値からの変わり方を読む。ここでは 0 → 1 → 2 → 4。2倍ずつ育っていると分かれば、式は 前の値 × 2 + 読んだ桁。変わり方がそのまま式になります。添字の向きは i = 1 を代入すれば1手で決まります。

答え合わせ ── result が 0 から 18 まで育つ

空欄に エ を入れて、convDecimal("10010") を最後まで動かします。result の欄と、いま読んでいる文字(▲)を見てください。

1行ずつ追う 正解の エ(result × 2 + int(binary の i文字目の文字))

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


ループ開始前

binary の文字(左から1文字ずつ。読むだけで、書き換えません)

▲ いま読んでいる

いま計算していること

まだ計算していません

変数の状態

トレース表(進めると1行ずつ積み上がります)

正解は エ

result ← result × 2 + int(binary の i文字目の文字)。2倍が「桁を1つ上げる」役、int(…) が「新しい桁を足す」役です。

ほかの3つは、この2つの役のどちらかが壊れています。解答群の4つは、「2倍あり/なし」と「左から/右から」の組合せでできていました。

選択肢 "10010" で返る値 何が起きるか
result + int(… (length - i + 1)文字目 …)(ア) 2 2倍が無いので桁が上がらず、1 の文字を数えているだけになります
result + int(… i文字目 …)(イ) 2 同じく2倍が無い。ア と イ は返す値がいつも同じです ── どちらも全部の文字を1回ずつ足すだけなので、読む向きは和に効きません
result × 2 + int(… (length - i + 1)文字目 …)(ウ) 9 2倍はありますが右から読んでいます。10010 を逆に並べた 01001 を読んだ値です

「1文字ずつ数を育てる」問題を見分ける

同じ形は、このあと何度も出てきます。見るところは2つです。

見るところ 読み取ること
この形だと気づく合図 結果を入れる箱が1つだけあって、くり返しの中でその箱に、その箱自身を使って代入している(result ← result …)。途中の値をぜんぶ並べて残す入れ物がないのが目印です
倍率は、その数の「桁の上がり方」で決まる 2進数なら2倍、10進数なら10倍。足すだけの集計なら倍率はありません(× 2 のような項が式に出てこない)。何進数の話かを先に決めると、倍率が自動で決まります

次に読む

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

この記事で引用した資料

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

Copied title and URL