配列の問題の解き方
飛岡拓希公開
配列の問題で失点するのは、ほとんどが要素番号の1つずれです。 要素番号と値を表に書き、ループの最初の回と最後の回だけを先に確かめると、ずれに気づけます。
要素番号は1から始まる
科目B の問題では、ほとんどの場合「配列の要素番号は 1 から始まる」と問題文に書かれています。 要素数が5なら、使える要素番号は 1 から 5 です。 プログラミングの経験がある人ほど 0 から数えてしまうので、問題文の一文を必ず確かめてください。
まず、配列を次のような表に書きます。値の上に要素番号を添えるのがコツです。
要素番号: 1 2 3 4 5 値 : 3 5 2 8 9
data[i - 1] のような式が出てきたら、表の上で指を1つ左へずらすと考えます。 頭の中で番号を足し引きするより、表を指でたどる方が間違えません。
ループは、最初の回と最後の回を先に確かめる
次の関数は、1つ前の要素より大きくなった回数を数えます。
○整数型: countUp(整数型の配列: data)
整数型: count ← 0
整数型: i
for (i を 2 から dataの要素数 まで 1 ずつ増やす)
if (data[i] > data[i - 1])
count ← count + 1
endif
endfor
return count全部を追う前に、i が一番小さい回と一番大きい回で、式が配列の外を指していないかを見ます。
- ・最初の回(i = 2):
data[2]とdata[1]。どちらも配列の中 - ・最後の回(i = 5):
data[5]とdata[4]。どちらも配列の中
もしループが i = 1 から始まっていたら、最初の回で data[0] を読むことになり、配列の外です。2 から始まっているのは、1つ前の要素と比べるからだと分かります。 穴埋めでループの範囲を選ぶ問題は、この2回を試すだけで選択肢をかなり減らせます。
確かめたら、表に1行ずつ書いて追います。
| i | 比べるもの | count |
|---|---|---|
| 2 | 5 > 3 → 増やす | 1 |
| 3 | 2 > 5 → 増やさない | 1 |
| 4 | 8 > 2 → 増やす | 2 |
| 5 | 9 > 8 → 増やす | 3 |
data が {3, 5, 2, 8, 9} のとき、戻り値は 3 です。
同じ配列の中で動かすときは、上書きの順番を見る
配列の中で値を前や後ろへずらす問題では、まだ読んでいない値を先に上書きしていないかが問われます。 次は、要素番号 k の要素を取り除き、後ろの要素を1つずつ前へ詰める手続です。
○remove(整数型の配列: data, 整数型: k)
整数型: n ← dataの要素数
整数型: i
for (i を k から n - 1 まで 1 ずつ増やす)
data[i] ← data[i + 1]
endfor
data の末尾の要素を取り除く{3, 5, 2, 8, 9} で k = 2 のとき、表はこう変わります。
はじめ : 3 5 2 8 9 i = 2 : 3 2 2 8 9 ← data[2] に data[3] を入れる i = 3 : 3 2 8 8 9 ← data[3] に data[4] を入れる i = 4 : 3 2 8 9 9 ← data[4] に data[5] を入れる 末尾を除く: 3 2 8 9
前へ詰めるときは、前から順に回します。data[2] を書き換える時点で、元の data[2] の 5 はもう要らないからです。
逆向き(後ろへずらす)のときに同じく前から回すと、書き換えた値をすぐ次の回で読んでしまい、 同じ値が並ぶだけになります。どちら向きに回すかは、「コピー元を、上書きされる前に読めるか」で決まります。表に1回ずつ書けば、崩れた瞬間が目で見えます。
この考え方で解ける問題(ずらす向きが逆の問題もあります):
- 配列を右に1つずらす巡回シフトを穴埋めする(難易度 2・登録なしで解けます)
- リングバッファで先頭と末尾を循環させる式を選ぶ(難易度 3・登録なしで解けます)
2次元配列は、[行, 列] の順
2次元配列は {{1, 2, 3}, {4, 5, 6}} のように書き、内側の {} が1行分です。 要素は data[行番号, 列番号] で指します。この例では data[2, 1] が 4 です。
列1 列2 列3 行1 : 1 2 3 行2 : 4 5 6
ループが二重になっているときは、外側のループが行、内側が列か、その逆かを最初に確かめます。 外側が行なら「1行目を左から右へ、次に2行目を…」の順に読むことになります。 表の上に、読んだ順の番号を小さく書いておくと迷いません。
mod が出てきたら、末尾と途中の番号を入れてみる
mod(割った余り)を使った式は、要素番号が末尾まで来たら先頭へ戻すためによく使われます。 式を選ぶ問題では、選択肢の式に、末尾の要素番号と途中の要素番号を入れてみるのが一番速い確かめ方です。
たとえば要素数 n = 5 で「次の要素番号」を求める式として (i + 1) mod n が並んでいたら、 i = 4 を入れると 5 mod 5 = 0 になります。要素番号 0 は無いので、この式は違うと分かります。
- ・末尾(i = n)を入れて、先頭の 1 に戻るか
- ・途中(i = 2 など)を入れて、1つ先の番号になるか
- ・どの i でも、1 から n の範囲に収まるか
要素番号が 1 から始まるので、0 から始まる言語で覚えた式をそのまま当てはめると、たいてい1つずれます。 覚えた式を探すより、数字を入れる方が確実です。
ほかの分野の解き方
解いたあとに解説を読む
このサイト(極とれ)の問題は、解いたあとにトレースの手順と、 選択肢ごとに「なぜ違うか」が開きます。登録なしで解けます。
配列の練習問題を見る記法は IPA が公開しているサンプル問題・公開問題の記述形式に基づいています。 出題形式は改訂されることがあるため、受験の際は IPA の公表内容をご確認ください。
この記事について
書いているのは飛岡拓希です。基本情報技術者試験の科目B だけを扱う学習サービス「極とれ」を 1人で作って運営しています。試験には高校3年生のときに合格しました(そのときの記録)。
数字を載せるときは、出典の資料を自分で開いて数えた値だけを使い、いつ時点のものかを本文に書いています。 誤りに気づいたら goku.tore9@gmail.com までお知らせください。読んだ感想はフォームからも送れます。