ITパスポート 2024年 問85
問題文
関数binaryToIntegerは、1桁以上の符号なし2進数を文字列で表した値を引数binaryStrで受け取り、その値を整数に変換した結果を戻り値とする。例えば、引数として“100”を受け取ると、4を返す。プログラム中のa, bに入れる字句の適切な組合せはどれか。
〔プログラム〕
○整数型: binaryToInteger(文字列型: binaryStr)
整数型: integerNum, digitNum, exponent, i
integerNum ← 0
for (iを1からbinaryStrの文字数まで1ずつ増やす)
digitNum ← binaryStrの末尾からi番目の文字を整数型に変換した値
//例:文字“1”であれば整数値1に変換
exponent ← [ a ]
integerNum ← [ b ]
endfor
return integerNum

選択肢
ア:
イ:
ウ:
エ:(正解)
🔒 解説は解答すると表示されます
2進文字列を整数に変換する関数の穴埋め問題【ITパスポート 解説】
正解の理由
この関数は、文字列で表された符号なし2進数(2進数:0と1だけで表す数)を整数に変換します。問題のループは文字列の末尾(下位ビット)から順に処理していきます。末尾から i 番目のビットの重み(価値)は です。したがって、各ステップで現在のビット値(digitNum)に重み(exponent)を掛け、その結果をこれまでの合計(integerNum)に足し合わせる必要があります。
これに一致する選択肢が エ の組合せです。
これに一致する選択肢が エ の組合せです。
(手短に:exponent = 、integerNum ← integerNum + digitNum × exponent)
解法ステップ
- 問題のループは「末尾から i 番目」を扱っている点を確認します。末尾は最下位ビット(2^0の位置)です。
- したがって i = 1 のとき重みは 、i = 2 のとき …となるので、重みは (これが a に入る式)です。
- 各ビットが持つ値は「ビット × 重み」です。合計はこれらを足し合わせて得られます。よって更新式は integerNum ← integerNum + digitNum × exponent(これが b に入る式)です。
- 以上から a に 、b に integerNum + digitNum × exponent を入れる選択肢が正しいと分かります(エ)。
簡単な例で確認(binaryStr = "100"):
- 長さ3。i=1: 末尾ビット=0、exponent= → integerNum += 0×1 = 0
- i=2: 末尾から2番目=0、exponent= → integerNum += 0×2 = 0
- i=3: 末尾から3番目=1、exponent= → integerNum += 1×4 = 4
結果は 4(期待通り)。
選択肢別の誤答解説
-
ア:a が ()となっており、これは重みではありません。たとえば i=1 で だが i=2 で となり、正しい重み と一致しません。さらに b が integerNum × digitNum × exponent で、これは「累積値を次のステップでさらに掛ける」式になり誤りです。合計を求めるべきところを掛け算してしまいます。
-
イ:a が で上と同じく重みがズレています。b は合計を足す形なので部分的には正しいが、exponent が間違っているため誤りです。
-
ウ:a は正しく ですが、b が integerNum × digitNum × exponent になっており、これでは「これまでの合計に現在のビットの価値を足す」処理になりません。たとえば最初のビットで integerNum が 0 であれば常に 0 のままになりやすく、正しい変換になりません。
よくある誤解
-
「指数(exponent)を にすればよい」と考える誤り
- ループが i を 1 から始め、末尾(最下位ビット)を i=1 としている場合、重みは です。i を 0 から始めるなら でも良いですが、問題文の定義に合わせることが重要です(オフバイワン=1ずれのミス)。
-
「累積変数(integerNum)を掛け算で更新する」誤り
- 新しいビットの寄与は「足し算」で累積します。掛け算にすると元の合計を歪めます。別の正しい方法として、左から処理する場合は integerNum ← integerNum × 2 + digitNum としても良い(後述)。
補足コラム
-
末尾(右端)から処理する方法と先頭(左端)から処理する方法の2通りあります。問題は末尾から処理していますが、左から順に処理する簡潔なアルゴリズムも覚えておくと便利です。
左から処理する方法(例:"1011" を左から):- 初期 integerNum = 0
- 各文字 digit(0か1)について: integerNum ← integerNum × 2 + digit
- これを繰り返すと最終的に正しい10進整数が得られます。
この方法は重みを明示的に計算しなくてよいので実装が楽です。
-
変換の一般原理は「桁ごとに(桁の値)×(基数の桁重み)を足す」です。2進数なら基数は 2、10進数なら基数は 10 です。
Pythonでの例(末尾から処理する場合):
def binary_to_integer(binary_str):
integer_num = 0
n = len(binary_str)
for i in range(1, n+1): # i = 1..n
digit = int(binary_str[-i]) # 末尾からi番目の文字を整数に
exponent = 2**(i-1)
integer_num += digit * exponent
return integer_num
左から処理する簡潔な例:
def binary_to_integer_left(binary_str):
integer_num = 0
for ch in binary_str: # 先頭から順に
digit = int(ch)
integer_num = integer_num * 2 + digit
return integer_num
FAQ
Q1. ループを i=0 から始めてもいいですか?
A1. はい。ただしその場合 exponent は にします。問題の定義(i を 1 から数える)に合わせて式を選んでください。
A1. はい。ただしその場合 exponent は にします。問題の定義(i を 1 から数える)に合わせて式を選んでください。
Q2. digitNum はどうやって得るのですか?
A2. 文字 '0'/'1' を整数に変換します。多くの言語では int('1') → 1 になります。あるいは文字コード差で 1 や 0 に変換する方法もあります。
A2. 文字 '0'/'1' を整数に変換します。多くの言語では int('1') → 1 になります。あるいは文字コード差で 1 や 0 に変換する方法もあります。
Q3. なぜ b は「足し算」なのですか?
A3. 2進数の値は各桁の「桁の値の合計」で決まります(例:101 = 1×2^2 + 0×2^1 + 1×2^0)。したがって各桁の寄与を合計に加えます。
A3. 2進数の値は各桁の「桁の値の合計」で決まります(例:101 = 1×2^2 + 0×2^1 + 1×2^0)。したがって各桁の寄与を合計に加えます。
関連キーワード: 2進数、基数変換、ビット操作、オフバイワンエラー、累積和、アルゴリズム、文字列操作

\ せっかくなら /
ITパスポートを
クイズ形式で学習しませんか?
クイズ画面へ遷移する→
すぐに利用可能!

