IT1-CODE-POCKET

線形探索シミュレーター

線形探索(逐次探索)は、配列の先頭から順番に1つずつ値を比べていく、もっとも基本的な探索です。 要素数(4〜10個)と場面を選び、1ステップずつ止めて動きを確認できます。

動きを1ステップずつ確認する

要素数(個)
場面
配列 Nums target 9
    • 比較中
    • 不一致
    • 一致・記録
    • 一致・無視
    i
    pos -1
    比較 0
    STEP 1 / 1 読み込み中です。

    パソコンではキーボードでも操作できます: 次へ / 前へ / スペース 再生・一時停止

    数値を自分で入力する

    カンマ区切りで 0〜99 の整数を入力します。擬似コードの1行目・2行目も自動で同じ内容に変わります。

    実行ログを見る(ここまでの処理)

      ALGORITHM

      線形探索とは何をしているか

      線形探索は、配列の先頭(添字 0)から末尾まで順番に進みながら、それぞれの要素を探したい値 target と比べていくアルゴリズムです。 「逐次探索」「順次探索」とも呼ばれます。やっていることは、机の上に並んだカードを左から1枚ずつめくって目的のカードを探す作業とまったく同じです。

      処理に必要な部品は3つだけです。どこを見ているかを表す添字 i見つかった位置を覚えておく変数 pos、そして要素と target を比べる条件式です。 上のシミュレーターで「次へ」を押していくと、この3つがどう変化していくかを1ステップずつ確認できます。

      考え方は単純ですが、共通テスト「情報Ⅰ」では 添字 i の進み方見つからなかったときの値同じ値が複数あるときの扱い比較回数が繰り返し問われます。 つまり「なんとなく分かる」では足りず、1行ずつ値を追える状態にしておく必要があります。

      なぜ pos の初期値は -1 なのか

      配列の添字は 0 から始まります。そのため pos = 0 を初期値にしてしまうと、「先頭の要素が見つかった」場合と「まだ何も見つかっていない」場合を区別できなくなります。 添字としては絶対にあり得ない値である -1 を初期値にしておけば、最後まで pos が -1 のままなら「配列の中に target は存在しなかった」と判断できます。 シミュレーターの「見つからない」プリセットを試すと、最後まで -1 が残る様子が確認できます。

      整列されていなくても使える

      線形探索の大きな特徴は、配列が小さい順に並んでいなくても正しく動くことです。先頭から全部見ていくのだから、並び方は結果に影響しません。 「整列済みでなければ使えない」という制約があるのは二分探索のほうです。この2つはセットで問われやすいので、前提条件の違いをはっきり区別しておきましょう。

      同じ値が複数あるときの扱い

      配列に target と同じ値が2つ以上あるとき、「どの位置を答えとするか」は条件の書き方で決まります。シミュレーターの「条件の書き方」を切り替えると、この違いをそのまま比較できます。

      条件の書き方 結果 比較回数
      Nums[i] == target かつ pos == -1 最初に見つかった位置 n 回(最後まで見る)
      Nums[i] == target で繰り返しを抜ける 最初に見つかった位置 見つかるまで
      Nums[i] == target(条件なしで代入) 最後に見つかった位置 n 回(最後まで見る)
      ポイント:上の1番目と2番目は答えは同じでも比較回数が違います。 「何回比較したか」を答えさせる問題では、繰り返しを抜ける処理があるかどうかを必ず確認してください。

      CODE

      3つの書き方で見る線形探索

      同じアルゴリズムを、共通テストの擬似言語(DNCL風)・Python・JavaScript で並べました。 変数名と処理の順番はすべて揃えてあるので、言語が変わってもやっていることは同じだと確認できます。

      Nums = [4, 9, 2, 9, 6]
      target = 9
      pos = -1
      
      i を 0 から 要素数(Nums) - 1 まで 1 ずつ増やしながら繰り返す:
      |もし Nums[i] == target かつ pos == -1 ならば:
      ⎿⎿ pos = i
      
      表示する(pos)
      繰り返しの範囲に注意:擬似言語の「0 から 要素数 - 1 まで」、Python の range(len(nums))、JavaScript の i < nums.length は、 すべて同じ範囲(添字 0 から n-1 まで)を表しています。書き方が違うだけで、末尾を含めて1回ずつ調べる点は共通です。

      COST

      比較回数と計算量

      線形探索の手間は「何回比較したか」で測ります。要素数を n として整理すると次のようになります。 シミュレーターで「先頭にある(最良)」と「末尾にある(最悪)」を切り替え、変数「比較回数」の最終値を見比べてみてください。

      場合 どんなとき 比較回数 計算量
      最良 target が先頭(添字 0)にある 1 回 O(1)
      平均 target が配列のどこかにある 約 n / 2 回 O(n)
      最悪 target が末尾にある、または存在しない n 回 O(n)

      要素数を変えて確かめる:シミュレーターの「要素数を選ぶ」で 4個 → 10個 と増やしながら「末尾にある(最悪)」を試すと、 最終的な比較回数が 4回 → 10回 と、要素数とぴったり同じだけ増えていくことが確認できます。 「見つからない」を選んだ場合も同じで、要素数と等しい回数になります。この2つが最悪の場合です。

      要素数が2倍になれば、かかる手間もおよそ2倍になります。これが O(n)(要素数に比例する)という意味です。 1000個の配列なら最悪1000回、100万個なら最悪100万回の比較が必要です。 一方、整列済みの配列に対して使える二分探索は、1回の比較で候補を半分に減らせるため、100万個でも約20回で済みます。 この差が「整列してから探す」意味につながります。

      EXAM POINT

      共通テスト「情報Ⅰ」での出題ポイント

      線形探索そのものを一から書かせる問題より、穴埋めトレース(値の追跡)として出るほうが多いです。狙われやすいのは次の5点です。

      1. 繰り返しの終了値:「0 から 要素数 - 1 まで」の - 1 が空欄になる形。0 から数え始めるので、最後の添字は n ではなく n-1 です。
      2. 見つからなかったときの値:pos = -1 の初期化や、「-1 のとき何を表示するか」を問う形。
      3. 条件式の空欄:Nums[i] == target の比較演算子や、かつ pos == -1 の部分。ここが変わると答えが「最初の位置」か「最後の位置」かで変わります。
      4. 比較回数を数える:変数 count を増やす行を追加した形。繰り返しを抜ける処理があるかどうかで答えが変わります。
      5. 添字が1始まりの問題文:「1番目の商品」のように日常の言い方と添字がずれる形。問題文の「〇番目」と配列の添字 i の対応を必ず確認します。
      トレース問題のコツ:紙の上に ipos の欄を作り、1行ずつ値を書き換えていくのが一番確実です。 上のシミュレーターは、その手作業を画面上でやっているだけです。まず自分で予測し、その後シミュレーターで答え合わせすると力がつきます。

      MISTAKES

      よくある間違い

      間違い 何が起きるか 正しくは
      繰り返しを「要素数まで」にする 存在しない添字 n を参照してエラーになる 「要素数 - 1 まで」にする
      pos の初期値を 0 にする 先頭で見つかった場合と見つからない場合を区別できない 添字にあり得ない -1 を使う
      条件に pos == -1 を入れ忘れる 同じ値が複数あると、最後の位置で上書きされる 最初の位置が必要なら条件を足す、または繰り返しを抜ける
      整列済みでないと使えないと思う 使える場面で選択肢から外してしまう 整列が前提なのは二分探索だけ
      見つけた後も比較回数を数え続ける 繰り返しを抜けるコードで比較回数を多く答えてしまう 抜ける処理があれば、そこで数えるのを止める

      CHECK

      理解度チェック

      まず自分で考え、答えを開く前に上のシミュレーターで確かめてみてください。

      Q1. Nums = [4, 9, 2, 7, 6] で target = 6 のとき、pos と比較回数はいくつになりますか。
      pos = 4、比較回数 5 回。 6 は末尾(添字 4)にあるため、先頭から末尾まですべて調べることになります。これが線形探索の最悪の場合で、要素数 n = 5 と比較回数が一致します。 (シミュレーターで「5個」+「末尾にある(最悪)」を選ぶとこの場面になります。)
      Q2. Nums = [4, 9, 2, 9, 6] で target = 9 のとき、条件から「かつ pos == -1」を取り除くと pos はいくつになりますか。
      pos = 3。 条件がないと、添字 1 で pos = 1 を記録した後、添字 3 でもう一度一致して pos = 3 に上書きされます。 結果として「最後に見つかった位置」が残ります。「かつ pos == -1」は最初の位置を守るための条件だと理解しておきましょう。
      Q3. 要素数 8 の配列に target が含まれていないとき、比較回数は何回になりますか。
      8 回。 存在しないことを確かめるには全要素を調べるしかないため、比較回数は要素数と同じ n 回になります。 このとき pos は初期値の -1 のままです。「見つからない」場合も最悪の場合に含まれる点に注意してください。 (シミュレーターで「8個」+「見つからない」を選ぶと確認できます。)
      Q4. 「見つけたら繰り返しを抜ける」書き方に変えると、必ず速くなりますか。
      いいえ、速くなるとは限りません。 target が末尾にある場合や存在しない場合は、抜ける機会がないため比較回数は変わらず n 回です。 短くなるのは「目的の値が前のほうにある」ときだけで、最悪の場合の計算量は O(n) のままです。

      次に確認したいアルゴリズム