戦国IT - 情報処理技術者試験の過去問対策サイト
ブログお知らせお問い合わせ料金プラン

応用情報技術者 2011年 秋期 午前208


問題文

データが昇順にソートされた配列Xiを2分探索する。流れ図のaに入るものとして、適切なものはどれか。ここで、流れ図の中の割り算は小数点以下を切り捨てるものとする。
応用情報技術者 2011年 秋期 午前2 問08の問題画像

選択肢

left < right
left ≦ right(正解)
left + 1 < right
left + 1 ≦ right

🔒 解説は解答すると表示されます

二分探索のループ条件【午前2解説】

正解の理由

探索ループは探索値が見つかっていない(sch == −1)かつ探索対象の範囲が存在する間に継続する必要があります。配列の有効範囲を左右のインデックスで表すと、要素が存在するのは のときです。したがって、選択肢の条件「left ≦ right」をループ継続条件に用べきです。これにより、範囲が1要素のとき()でもその要素を調べる反復が行われ、見落としが生じません。
(流れ図では sch が見つかったら sch に index を格納してループを終わらせるため、ループ条件は (sch == −1) と (left ≦ right) の論理積になります。)

解法ステップ

  1. 配列が昇順でソートされているため、中央値 center を計算して比較し、探索範囲を半分にする二分探索の基本に従う。
  2. ループを継続すべきときは「未発見で、かつまだ探索すべき要素が残っている場合」であり、探索すべき要素が残っていることは で判定する。
  3. 各反復で center ← (left + right) ÷ 2(小数点以下切り捨て)を計算し、X[center] と探索値を比較する。
    • 小さいとき: left ← center + 1
    • 等しいとき: sch ← center(探索成功、ループ条件の sch == −1 が false になり終了)
    • 大きいとき: right ← center − 1
  4. ループを抜けたら sch を表示(見つからなければ -1 のまま)。

選択肢別の誤答解説

  • ア: left < right
    left < right は「範囲に2以上の要素があるときのみ継続」する条件です。これだと範囲がちょうど1要素()のときループを行わず、その単独要素の比較を行わないため、存在する要素を見逃す可能性があります。従って不適切です。
  • イ: left ≦ right
    これは正答です。範囲に1要素ある場合()もループを継続して比較を行うため、正しく動作します。流れ図の中心計算と左右更新(center ± 1)と組み合わせると、探索が適切に収束します。
  • ウ: left + 1 < right
    left + 1 < right は right − left ≥ 2、つまり「範囲が3要素以上のときのみ継続」する条件に相当します。これでは範囲が1要素や2要素のときにループを中断してしまい、正しい検索結果を得られません。
  • エ: left + 1 ≦ right
    left + 1 ≦ right は right − left ≥ 1、すなわち「範囲が2要素以上のとき継続」する条件です。範囲が2要素のときは継続しますが、範囲が1要素()のときはループを終了してしまいます。したがって単一要素を検査できず、誤検出を招きます。
(注意:左辺に +1 が入る条件は「2要素以上」を判定するものになり、1要素のときは継続しない点が重要です。)

よくある誤解

  • 等号の有無を軽視する誤り:while の条件で ≤ を使うべきか < を使うべきか迷い、単一要素の検査を抜かすミスが多いです。二分探索では人為的な off-by-one を招きやすいので注意してください。
  • center の算出で切り捨て方を混同:中心計算は整数除算(切り捨て)で行うこと。言語によっては負数の切り捨て挙動が異なるので注意が必要です。
  • 中央値計算のオーバーフローを無視:大きな配列で (left + right) が整数の上限を超える場合があります。安全には center ← left + (right - left) ÷ 2 を用いる実装が好まれます。

補足コラム

  • ループ条件を while (left <= right) にしておけば、見つかれば即座に sch を更新してループを抜ける設計と自然に合います。別の実装スタイルとして while (left < right) を用いることもありますが、その場合は center の偏り(左寄せ/右寄せ)やループ内の更新法を工夫して、最終的に残る1要素を別途チェックする必要があります。
  • 中央値計算のオーバーフロー回避例:center = left + (right - left) // 2
コード例(Python)
def binary_search(X, target):
    sch = -1
    left = 0
    right = len(X) - 1
    while sch == -1 and left <= right:  # <mark>イ</mark> に対応
        center = left + (right - left) // 2
        if X[center] < target:
            left = center + 1
        elif X[center] == target:
            sch = center
        else:
            right = center - 1
    return sch

FAQ

Q. while (left < right) と while (left <= right)、どちらが良いですか?
A. 基本形としては while (left <= right) が分かりやすく安全です。while (left < right) を使う場合はループ後に残る 1 要素を別途チェックする実装上の配慮が必要です。
Q. center の計算で (left + right) // 2 と left + (right - left) // 2 の違いは?
A. 結果は同等ですが、前者は left + right が大きくなるとオーバーフローする可能性があります。安全性を考えると後者(差を使う方法)が推奨されます。

関連キーワード: 二分探索、境界条件、中心計算、オフバイワン、探索アルゴリズム
← 前の問題へこの年度をクイズで解く次の問題へ →
戦国ITクイズ機能

\ せっかくなら /

応用情報技術者
クイズ形式で学習しませんか?

クイズ画面へ遷移する

すぐに利用可能!

©︎2026 情報処理技術者試験対策アプリ

このサイトについてブログプライバシーポリシー利用規約特商法表記開発者について