本文へスキップ
BecomeCoder

COBOLコース · 第6章 表を扱う ― OCCURSと配列 · レッスン33

SEARCH文 ― 表から探す(線形探索・SEARCH ALL)

ローカル実施

導入

表の中から「特定の条件に合う要素」を探したいとき、PERFORMループを回しながらIFで調べる方法もありますが、COBOLには表探索専用の SEARCH文 が用意されています。

説明

SEARCH(線形探索) は、表の先頭から1つずつ順番に調べていきます。

       01  WS-NAMES.
           05  WS-NAME          PIC X(10)  OCCURS 5 TIMES
                                            INDEXED BY WS-NAME-IDX.
       01  WS-FOUND-FLAG        PIC X(1)   VALUE "N".

       PROCEDURE DIVISION.
      *>  (事前に WS-NAME(1)〜WS-NAME(5) に名前を入れてある想定)
           SEARCH WS-NAME
               AT END
                   DISPLAY "見つかりませんでした"
               WHEN WS-NAME(WS-NAME-IDX) = "SUZUKI"
                   MOVE "Y" TO WS-FOUND-FLAG
                   DISPLAY "見つかりました: " WS-NAME-IDX
           END-SEARCH.
  • SEARCH WS-NAMEINDEXED BY で宣言したインデックスWS-NAME-IDX)を使って、WS-NAME の表を先頭から調べる。
  • WHEN 条件 … 条件に一致した時点で探索を終了し、その節の処理を実行する。このとき WS-NAME-IDX には見つかった位置が入っている。
  • AT END … 表の最後まで調べても見つからなかった場合の処理。

SEARCH ALL(二分探索) は、表があらかじめキー順に並んでいることが前提の、より高速な探索方法です。

       01  WS-CODES.
           05  WS-CODE          PIC 9(4)   OCCURS 100 TIMES
                                            ASCENDING KEY IS WS-CODE
                                            INDEXED BY WS-CODE-IDX.

       PROCEDURE DIVISION.
           SEARCH ALL WS-CODE
               AT END
                   DISPLAY "コードが見つかりません"
               WHEN WS-CODE(WS-CODE-IDX) = 1050
                   DISPLAY "見つかった位置: " WS-CODE-IDX
           END-SEARCH.
  • ASCENDING KEY IS WS-CODE … 表があらかじめ昇順(小さい順)に並んでいることを宣言する。これがSEARCH ALLを使うための前提条件です。
  • SEARCH ALL は、100件の表なら最悪でも約7回程度の比較で見つけられる二分探索アルゴリズムを、コンパイラが自動で実装してくれます。線形探索の SEARCH(最悪100回の比較)より効率的です。

表が小さいうちは SEARCH で十分ですが、数百〜数千件規模の表を何度も検索するような処理では SEARCH ALL(二分探索)が効果を発揮します。ただし表を事前にソートしておく必要がある点を忘れないようにしましょう。

試すには

レッスン30で作った5人分の点数表に名前を追加し、SEARCH で「名前が”YAMADA”の人の点数」を探すコードを書いてみましょう。見つかった位置のインデックスを使って、対応する点数もあわせてDISPLAYしてみてください。