基本情報技術者

問2

基本情報技術者試験過去問 令和6年度(2024年)科目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文字目の文字)

正解と解き方・学習ポイント(AI解説)

正解:
あなたの回答:未回答

2進数の文字列を左から1文字ずつ処理する場合、これまでの値を2倍して(1桁左に進めて)から、読んだ文字を0または1として加えます。for文の各回でresultを更新する式は、result × 2 + int(binaryのi文字目の文字)となるので正解は「エ」です。

不正解

(length-i+1)文字目を参照しているので右端から読む形です。さらに式が result + int(...) だけで、桁が進むごとに重みが2倍になる性質(×2)が反映されません。よって誤りです。

不正解

result + int(binaryのi文字目の文字) も、resultを2倍する処理がありません。よって、2進数としての桁の重みを表現できず、正しい10進数になりません。よって誤りです。

不正解

result × 2 + int(binaryの(length-i+1)文字目の文字) は2倍の処理はありますが、参照しているのが右端から左端の順です。左から順に処理する更新式としては扱えないため、期待する変換結果になりません。よって誤りです。

正解

result × 2 + int(binaryのi文字目の文字) は、左端から順に文字を読み、resultを2倍してから現在の桁(0または1)を加算します。2進数を10進数へ変換する更新式になっているため正解です。

Point

この問題は、2進数を左から順に読み取って10進数に変換する際の更新式(result = result × 2 + ビット)を理解しているかを確認しています。あわせて、for文で参照している文字位置がi文字目(左から)である点を読み取れるかも確認しています。

解くために必要な知識

この問題を解くには、2進数の桁の重みと、文字列を左から順に処理して数値に変換する更新式を理解している必要があります。

用語の整理

用語 内容
2進数 0と1で表す数です。右端の桁から順に重みが20、21、22、…になります。
10進数 0〜9で表す数です。日常的に使う表現です。
基数変換 ある進数(基数)の表現を、別の進数の表現に変換することです。
ホーナー法 左から順に処理し、これまでの値を基数倍してから次の桁を足す計算方法です。2進数では基数が2なので2倍します。
int関数(本問の定義) 文字が"0"なら0、"1"なら1を返す関数です。

左から処理する更新式(2進数の場合)

更新式

左から1文字ずつ読んだとき、resultの更新は次の形が原則です。

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

成立する理由

左から次の桁へ進むと、既に作った数は2倍された位置(1桁左)に移動します。
そのため、毎回resultを2倍し、現在の文字(0または1)を加算します。

具体例("10010")

"10010"を重みで書くと次のとおりです。

1×24 + 0×23 + 0×22 + 1×21 + 0×20

これを左からの更新式で計算すると、18になります。

問題の解法手順

解く手順

1. for文で処理する順番を確認する

iは1からlengthまで1ずつ増えます。
したがって、binaryの参照はi文字目を使うと、左端から右端へ順に処理できます。

2. 2進数の桁の重みを式で表す

左から順に処理する場合、各文字を読むたびに桁が1つ左へ進むので、これまでの値は2倍されます。
その上で、現在の桁の値(0または1)を足します。

更新式は次の形になります。

result = result × 2 + int(現在の文字)

3. 例で確認する(binary = "10010")

length = 5のとき、選択肢「エ」の式で処理すると次のとおりです。

i binaryのi文字目 int() 更新式 result
1 "1" 1 result = 0 × 2 + 1 1
2 "0" 0 result = 1 × 2 + 0 2
3 "0" 0 result = 2 × 2 + 0 4
4 "1" 1 result = 4 × 2 + 1 9
5 "0" 0 result = 9 × 2 + 0 18

期待どおり18になるため、正解は「エ」です。

選択肢ごとの解説

不正解

(length-i+1)文字目を参照しているので右端から読む形です。さらに式が result + int(...) だけで、桁が進むごとに重みが2倍になる性質(×2)が反映されません。よって誤りです。

不正解

result + int(binaryのi文字目の文字) も、resultを2倍する処理がありません。よって、2進数としての桁の重みを表現できず、正しい10進数になりません。よって誤りです。

不正解

result × 2 + int(binaryの(length-i+1)文字目の文字) は2倍の処理はありますが、参照しているのが右端から左端の順です。左から順に処理する更新式としては扱えないため、期待する変換結果になりません。よって誤りです。

正解

result × 2 + int(binaryのi文字目の文字) は、左端から順に文字を読み、resultを2倍してから現在の桁(0または1)を加算します。2進数を10進数へ変換する更新式になっているため正解です。

まとめ

2進数の文字列を左から1文字ずつ処理する場合、これまでの値を2倍して(1桁左に進めて)から、読んだ文字を0または1として加えます。for文の各回でresultを更新する式は、result × 2 + int(binaryのi文字目の文字)となるので正解は「エ」です。

順次、単語を追加予定です。もうしばらくお待ちください。