集計パターン
配列を1周して何かを求める
配列を扱うコードの大半は、先頭から末尾まで1周しながら1つの答えを作る形をしています。合計を出す、最大値を出す、条件に合う個数を数える。どれも見た目は違いますが、骨組みは同じです。
骨組みは次の3つの部品でできています。
- 答えを入れる変数を、ループに入る前に初期化する
- ループの中で、今見ている要素を使って答えを更新する
- ループを抜けたら、その変数を返す
この形を知っていると、初めて見るコードでも「これは集計だ」と当たりが付きます。科目Bでは、まずこの当たりを付けることが読解の第一歩になります。
合計を求める
合計の初期値は 0 です。0 は足しても答えを変えないので、安全に置いておけます。
sum ← 0
for (i を 1 から dataの要素数 まで 1 ずつ増やす)
sum ← sum + data[i]
endfor最大値を求める
最大値では、初期値の置き方が問われます。合計と同じ調子で 0 を入れてしまうと、要素がすべて負の数のときに答えが 0 になり、間違いになります。
そこで、先頭の要素そのものを初期値にします。
max ← data[1]ここでも添字が効いてきます。先頭は data[0] ではなく data[1] です。この1行を data[0] と書いた選択肢は、それだけで誤りだと判断できます。
先頭を初期値にしたので、ループは 2 から回しても構いません。1 から回しても、1回目の比較が「自分自身より大きいか」になって成り立たないだけなので、答えは同じです。今回のコードは 1 から回す書き方にしてあります。
更新の条件を読み違えない
最大値の更新は data[i] > max のときだけです。≧ になっていると、同じ値でも更新が走ります。答えの数字は変わりませんが、更新の回数を問う設問では差が出ます。不等号に等号が付いているかどうかは、必ず指で押さえて確認してください。
個数を数える形も同じ骨組み
条件に合う要素の個数を数えるコードも、部品の組み合わせは変わりません。答えの入れ物を 0 で初期化して、条件が成り立ったときだけ 1 を足します。
kosuu ← 0
for (i を 1 から dataの要素数 まで 1 ずつ増やす)
if (data[i] > 0)
kosuu ← kosuu + 1
endif
endfor足すものが data[i] なら合計、1 なら個数です。違いはそこだけなので、kosuu ← kosuu + data[i] と書かれた選択肢は個数ではなく合計になってしまい、誤りだと判断できます。
最小値と、位置を求める形
最小値は、不等号の向きを逆にするだけです。初期値はやはり data[1] を使います。
もう1つ、最大値そのものではなく「最大値が何番目にあるか」を問う形もあります。このときは、値を覚える変数の代わりに位置を覚える変数を置きます。
ichi ← 1
for (i を 2 から dataの要素数 まで 1 ずつ増やす)
if (data[i] > data[ichi])
ichi ← i
endif
endfor比べる相手が max ではなく data[ichi] になっている点に注目してください。覚えているのが位置なので、値を見るにはもう一度配列を引く必要があります。この形は探索の章でもう一度出てきます。
今回のトレースでは、合計と最大値を同時に求めます。data の初期値は {3, 1, 4} です。if の行を実行したときは、条件が成り立ったかどうかを note で確かめてください。
課題
- 各行を実行したあとの値を入れる
- 値が変わらない変数はそのままの値を入れる
- if の行では、条件を判定しただけで値は変わらない