配列の中から目当ての値を探す回です。やり方はいちばん素朴で、前から順に照らし合わせるだけ。これを線形探索といいます。
第2部 定番処理の型 全27回
A1-1トレース表の書き方A1-2繰返しのトレースA1-3配列のトレースA2-1配列を全部見るA2-2最大・最小を見つけるA2-3探す(線形探索)A2-4入れる・消すA2-52つの配列を突き合わせる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ファイル処理
まず、通しで見る
1分50秒ほどの動画です(音声つき)。線形探索で問われるのは、いつ止まるかと、見つからなかったときに何を返すかの2つです。前半は 90 を探して3番目で止まるところ、後半は 55 を探して最後まで見つからないところ。この2つを見ておくと、空欄がどこに置かれても答えを決められます。
動画で追いかけるのは、このプログラムです。
○整数型: sagasuIchi(整数型の配列: ten, 整数型: sagasu)
整数型: i
for (i を 1 から tenの要素数 まで 1 ずつ増やす)
if (ten[i] = sagasu)
return i
endif
endfor
return -1
線形探索の全体(2分18秒・音声つき)
再生できないときは、この下の図と説明で同じ内容を追えます。
ここから、同じ内容を1つずつ確かめていきます。
プログラムを、上から読む
まず、行ごとの役割です。線形探索は、どの問題でもこの形なので、ここを一度読んでおくと本番で組み立て直す必要がありません。
上から読む
-
○整数型: sagasuIchi(整数型の配列: ten, 整数型: sagasu)
-
整数型: i
番号を入れておく箱。いま何番目を見ているかが、ここに入ります。 -
for (i を 1 から tenの要素数 まで 1 ずつ増やす)
前から順に見る。iが 1、2、3 … と進みます。tenの要素数は配列に入っている値の個数なので、最後の要素まで来たら終わります。 -
if (ten[i] = sagasu) return i endif見つかったか。いま見ているten[i]が探す値と同じなら、その番号iを返します。同じでなければ何もせず、次の番号へ進みます。 -
endfor return -1
最後まで無かったとき。くり返しを回りきると、この行に来ます。ここで何を返すかは、この記事でいちばん問われるところなので、あとの節でくわしく見ます。
前から1つずつ、照らし合わせる
点数の配列から、90 が何番目にあるかを探します。
前から1つずつ、照らし合わせる
整数型の配列: ten ← {80, 65, 90, 72} / 90 が何番目にあるかを探す
i = 1 ten[1] = 90? 80 なので、ちがう
180▲
265
390
472
i = 2 ten[2] = 90? 65 なので、ちがう
180
265▲
390
472
i = 3 ten[3] = 90? 同じ ── 見つかった
180
265
390▲
472
return i で 3 を返し、関数はここで終わる
4番目は、見に行かない
180
265
390
472
探し物が見つかったら、そこで終わり。1000個あっても同じ
見つかった時点で止まる。だから最後まで回るとは限らない
1番目は 80、ちがう。2番目は 65、ちがう。3番目が 90 ── 見つかりました。
ここで大事なのは、4番目を見に行かないことです。探し物が見つかったら、そこで終わりです。
○整数型: sagasuIchi(整数型の配列: ten, 整数型: sagasu)
整数型: i
for (i を 1 から tenの要素数 まで 1 ずつ増やす)
if (ten[i] = sagasu)
return i
endif
endfor
return -1
線形探索を1行ずつ動かす
当サイトオリジナルの例題
ループ開始前
配列
いま計算していること
変数の状態
出力
トレース表(進めると1行ずつ積み上がります)
止め方は2通りある
「そこで止める」の書き方は、2つあります。どちらも出題に出てくるので、プログラムを見た瞬間にどちらか分かるようにしておきます。
① その場で return する
さきほどのプログラムがこれです。return i に来た瞬間、くり返しの途中でも関数を抜けて、呼び出し元へ戻ります(G3-3)。
if (ten[i] = sagasu)
return i
endif
3番目で見つかったら、4番目以降は1回も実行されません。1000個の配列でも、1番目に当たれば1周で終わります。
② 位置を箱に入れて、最後まで回る
関数ではなく、そのまま書き下す形です。見つけても止まらず、最後まで回りきってから箱の中身を見ます。
整数型の配列: ten ← {80, 65, 90, 72}
整数型: sagasu ← 90
整数型: ichi ← -1
整数型: i
for (i を 1 から tenの要素数 まで 1 ずつ増やす)
if (ten[i] = sagasu)
ichi ← i
endif
endfor
ichiの値 を出力する
出力は 3 です。①と答えは同じですが、4番目まで回ってから終わります。
もし ten が {90, 65, 90, 72} だったら、②は ichi に 1 を入れたあと3で上書きし、出力は 3 になります。①なら 1 で止まるので 1 です。
つまり①は最初の位置、②は最後の位置を答えます。問題文がどちらを求めているかを必ず読んでください。
見つからなかったときに、何を返すか
ここがいちばん問われるところです。最後まで見て無かったとき、何を返せばよいか。
見つからなかったときに返す値
見つかったときの答えは、必ず 1 以上
実在する要素番号は 1 から
-1-
0-
180
265
390
472
擬似言語の配列は1番目から数える。0 番や -1 番の箱は存在しない
だから -1 や 0 を返せば、呼んだ側は「無かった」と判断できる
擬似言語の配列は1番目から数えます。見つかったときの答えは、必ず 1 以上です。だから -1 や 0 を返しておけば、呼んだ側は「見つからなかった」と判断できます。-1 と 0 のどちらもよく使われます。
ただしどちらを返すかは、問題ごとに決まっています。問題文の説明か、クラスの表に必ず書かれています(G12-3)。自分で決めるものではありません。
return -1 は endfor の下にあります。くり返しの中に書いてはいけません。
中に書くと、1番目がちがった時点で「無かった」と答えてしまいます。全部見終わってからでないと、無いとは言えません。
つまずきポイントまとめ
| まちがえ方 | 正しい読み方 |
|---|---|
| 見つかったあとも回り続けると思う | return があればその場で戻る |
| 印を立てる形で、最初の位置を答える | あとのほうで上書きされる。最初を残すなら工夫が要る |
| 見つからないときに 0 を返して迷う | 要素番号は1から。0 も -1 もありえない番号だから印になる |
return -1 をくり返しの中に書く |
全部見終わってから。endfor の下に置く |
| 返す値を自分で決める | 問題文に書いてある。表か説明を読む |
次に読む
| A2-4 | 配列に入れる・消す ─ 末尾への追加とずらし方 |
| A2-2 | 最大・最小を見つける ─ 仮の王者を置いて入れ替える |
| G3-3 | 戻り値・手続と関数 ─ return で戻るということ |
| 目次 | 基本情報技術者試験 科目B 攻略ガイド |
この記事で引用した資料
いずれも独立行政法人情報処理推進機構(IPA)が公表したものです。IPAは公表済みの試験問題について、教育目的での使用に許諾および使用料を不要としていますが、著作権は放棄していません。本記事では問題文を改変せずに引用しています。
本文の例題は当サイトのオリジナルです。
