科目Bには、文字列を前から1文字ずつ読んで、答えを1つ作るプログラムが出ます。この回はその型を1本、最後まで読めるようにします。A2-1 でやった「全部見る」の、文字列版です。
第2部 定番処理の型 全26回
A1-1トレース表の書き方A1-2繰返しのトレースA1-3配列のトレースA2-1配列を全部見るA2-2最大・最小を見つけるA2-3探す(線形探索)A2-4入れる・消すA3-12次元配列の走査A3-22次元配列の集計A4-1文字列を1文字ずつA4-2文字列照合A5-1交換して並べるA5-2挿入ソートA6分割して並べるA7-12分探索A7-2ハッシュ表探索A8-1再帰とはA8-2再帰のトレースA9スタックとキューA10-1リストを読むA10-2リストの挿入と削除A11木構造A12木の巡回A13グラフA14AI・データを題材にしたプログラムA15ファイル処理
まず、通しで見る
3分ほどの動画です(音声つき)。result が 0 → 1 → 2 → 4 → 9 → 18 と育っていくところを、1周ずつ計算式ごと見せます。
後半は、なぜ × 2 で正しい答えになるのかを、237 = 23 × 10 + 7 から橋を架けて説明します。
1文字ずつ読んで、答えを育てる(2分56秒・音声つき)
再生できないときは、この下の図とシミュレータで同じ内容を追えます。
ここから、同じ内容を1つずつ確かめていきます。
この回で読めるようにするプログラム
やることは1つ。"10010" という文字の並びを受け取り、それを2進数と見たときの値 18 を返すことです。いま読めなくて構いません。
○整数型: convDecimal(文字列型: binary)
整数型: i
整数型: result ← 0
for (i を 1 から binaryの文字数 まで 1 ずつ増やす)
result ← result × 2 + int(binary の i文字目の文字)
endfor
return result
出典:令和6年度 基本情報技術者試験 科目B 公開問題 問2(空欄は正解で補い、長さの受け取りを省いています)
この回のゴール
このプログラムを1周ずつ自分で追って、18 を出せる。
その前に、この1行の × 2 だけ先に片づけます。ここが腑に落ちていないと、このあとの5周が、ただの手順に見えます。
"10010" を10進数にする計算として習ったのは、こちらのはずです。
1×16 + 0×8 + 0×4 + 1×2 + 0×1 = 18
プログラムはこの式を使っていません。使えないからです。1文字目の 1 は、"10010"(5文字)なら 16 の位ですが、"10010000"(8文字)なら 128 の位です。同じ1文字目でも、全体が何文字かで重みが変わる。前から読んでいる途中には、まだ決まらないのです。
そこで、重みを使わない読み方をします。10進数で考えると一瞬です。
237 = 23 × 10 + 7
23 の後ろに 7 が来て 237。1桁増えると、それまでの桁が全部ひとつ左へずれる=値がまるごと10倍。そこへ新しい桁を足すだけです。この式の3つが、そのままプログラムの3つになります。
23そこまで読んだ分 = result
7新しく読んだ桁 = int(…)
10何進数か = 2進数なら 2
習ったやり方とは道順が違うだけで、着く答えは同じです。
あとは、文字列を扱う書き方が2つと、int という関数だけです。それを片づけます。
要るのは、2つの書き方と1つの関数だけ
文字列は、1文字ずつ番号で取り出せる
文字列型: binary ← “10010”
binaryの文字数 は 5
11
20
30
41
50
文字列 “10010” を、1文字ずつ並べたところ
binary の 3文字目の文字 は "0"
11
20
30▲
41
50
配列の ten[3] と同じ考え方。番号は1から数える
要るのはこの2つの書き方と、int という関数だけ
文字列を扱う書き方
binaryの文字数その文字列が何文字か("10010" なら 5)
binary の i文字目の文字i 番目の1文字(3文字目なら "0")
配列の 要素数 と [i] に対応すると思えば十分です(配列側は G4-1)。取り出せるのは1文字なので、受けるなら 文字型 の箱です(G2-2)。
もう1つ、int という関数を使います。出題側が用意した関数で、引数で与えられた文字が “0” なら整数値 0 を、“1” なら整数値 1 を返します。取り出せるのは文字で、足したいのは数です。その間をつなぐのが int です。
18 になるまでを、1周ずつ追う
追うのは、この部分です。
整数型: result ← 0
for (i を 1 から binaryの文字数 まで 1 ずつ増やす)
result ← result × 2 + int(binary の i文字目の文字)
endfor
binary は "10010"、binaryの文字数 は 5。だから for は i が 1 から 5 まで5周します。
始まりは result ← 0。まだ1文字も読んでいないので 0 です。
1周ずつ
- i = 1。1文字目は
"1"。intが 1 にする。resultは0 × 2 + 1で 1。 - i = 2。2文字目は
"0"。intが 0 にする。resultは1 × 2 + 0で 2。 - i = 3。3文字目は
"0"。resultは2 × 2 + 0で 4。 - i = 4。4文字目は
"1"。resultは4 × 2 + 1で 9。 - i = 5。5文字目は
"0"。resultは9 × 2 + 0で 18。
i が 5 を超えて for が終わり、return result で 18 が返ります。
convDecimal(“10010”) を1行ずつ動かす
令和6年度 科目B 問2(空欄は正解で補ってあります)
ループ開始前
配列
いま計算していること
変数の状態
出力
トレース表(進めると1行ずつ積み上がります)
手順はこれで追えました。先に片づけた × 2 の理屈と合わせて、この型は最後まで読めます。押さえるのは2つです。
この型の読み方
答えの箱を 0 で始める → くり返しの中で1つずつ更新する → 最後に返す。
result ← result × 2 + 新しい桁 を見たら、「左から1桁ずつ、数を組み立てている」と読む。掛けている数が、そのまま何進数かです。
身についたかどうかは、別の文字列で1周ずつ追えるかで決まります。
先に、ひとつ予想してみましょう
次を実行したあと、result の値はいくつになりますか。int は "0" なら 0、"1" なら 1 を返す関数です。
文字列型: binary ← "1101" 整数型: i 整数型: result ← 0 for (i を 1 から binaryの文字数 まで 1 ずつ増やす) result ← result × 2 + int(binary の i文字目の文字) endfor
文字型の配列で来ても、やることは同じ
同じ「文字の並び」が、文字型の配列 で渡されることもあります(令和7年度 問4)。
文字型の配列で来ても、やることは同じ
同じ「文字の並び」でも、渡され方が2通りある(令和7年度 問4 は配列のほう)
文字列型で来たとき
11
20
30▲
41
50
取り出し方は binary の 3文字目の文字
文字型の配列で来たとき
11
20
30▲
41
50
取り出し方は data[3]。長さは dataの要素数
変わるのは取り出す書き方だけ。1文字ずつ見ていく形は同じ
○整数型: convFromArray(文字型の配列: data)
整数型: i
整数型: result ← 0
for (i を 1 から dataの要素数 まで 1 ずつ増やす)
result ← result × 2 + int(data[i])
endfor
return result
当サイトで作った例です。
convFromArray({"1", "0", "0", "1", "0"}) を呼ぶと、やはり 18。1行ずつ見比べてください。
変わるところ
文字列型: binary→ 文字型の配列: data(引数の宣言)
binaryの文字数→ dataの要素数(for の上限)
binary の i文字目の文字→ data[i](取り出し)
育て方は1行も変わりません。最初に宣言を見てください。
つまずきポイントまとめ
| まちがえ方 | 正しい読み方 |
|---|---|
| 答えの箱に 0 を入れ忘れる | まだ1文字も読んでいない=0。ここが空だと1周目から壊れる |
result + int(…) と × 2 を落とす |
本番の解答群にある誤答。桁が左へずれないので、1の個数を数えるだけになる |
+ を先に計算する |
掛け算が先。0 × (2 + 1) と読むと、値は最後まで 0 のまま |
binary[i] と書く |
文字列型 なら binary の i文字目の文字 |
binaryの要素数 と書く |
文字列に 要素数 は使わない。for の上限が決まらなくなる |
| 取り出したものを文字列型で受ける | 取り出せるのは1文字。受けるなら 文字型 |
次に読む
この記事で引用した資料
いずれも独立行政法人情報処理推進機構(IPA)が公表したものです。IPAは公表済みの試験問題について、教育目的での使用に許諾および使用料を不要としていますが、著作権は放棄していません。本記事では問題文を改変せずに引用しています。
本文の例題は当サイトのオリジナルです。
