8.検索文字列


検索文字列

  • 文字列検索とは、ある文字列に他の文字列が含まれているかどうかを調べ、その場所を検索することです.
  • 「STRING」で「IN」を検索すると3(インデックス)が返されます.
  • ブルートペルシャ法



    これは
  • の順序で逐一比較する方法である.
  • コード#コード#

    static int bfMath(String txt, String pat) {
      int pt = 0; // txt 커서
      int pp = 0; // pat 커서(찾는 문자열)
      
      while (pt != txt.length() && pp != pat.length()) {
        if (txt.charAt(pt) == pat.charAt(pp)) {
          pt++;
          pp++;
        } else {
          pt = pt - pp + 1;
          pp = 0;
        }
      }
      if (pp == pat.length())
        return pt - pp;
      return -1;
    }

    String.indexOf

  • java.lang.Stringクラスは、文字列を検索するindexOfメソッドとlastIndexOfメソッドを提供します.
  • int indexOf(String str)
  • int indexOf(String str, int fromIndex)
  • int lastIndexOf(String str):配列の後ろからstrを探します.
  • int lastIndexOf(String str, int fromIndex)
  • KMPメソッド

  • ブルート・フォス法は、他の文字に遭遇した場合、モードで文字の位置をチェックした結果を放棄し、1グリッドを次のテキストの位置に移動し、モードの最初の文字からチェックを開始します.
  • KMP法は検査位置結果を捨てない効率的なアルゴリズムである.
  • コード#コード#

    static int kmpMatch(String txt, String pat) {
      int pt = 1;
      int pp = 0;
      int[] skip = new int[pat.length() + 1]; // 건너뛰기 표
      
      skip[pt] = 0;
      while (pt != pat.length()) {
        if (pat.charAt(pt) == pat.charAt(pp))
          skip[++pt] = ++pp;
        else if (pp == 0)
          skip[++pt] = pp;
        else
         pp = skip[pp];
      }
    }

    Boyer-Moore法

  • KMP法よりも効率が高いのでよく使われています.
  • モードの最後の文字から前にチェックし、一致しない文字がある場合は、予め用意されたテーブルに基づいて移動するモードのサイズを決定します.
  • 以下の規則に従って、A~Zのテーブルを作成することができる.
  • モードでない文字に遭遇した場合:転送モードのサイズはnである.
  • モードの文字に遭遇
  • が最後に出現した位置のインデックスがkである場合、モード遷移のサイズはn−k−1である.
  • のような文字がパターンに重複していなければ、パターンを移動するサイズはnである.
  • コード#コード#

    static int bmMatch(string txt, String pat) {
      int pt;
      int pp;
      int txtLen = txt.length();
      int patLen = pat.length();
      int[] skip = new int[Character.MAX_VALUE + 1]; // 건너뛰기 표
      
      // 건너뛰기 표 만들기
      for (pt = 0; pt <= Character.MAX_VALUE; pt++)
        skip[pt] = patLen;
      for (pt = 0; pt < patLen - 1; pt++)
        skip[pat.charAt(pt)] = patLen - pt - 1;
        
      // 검색
      while (pt < txtLen) {
        pp = patLen - 1; // pat의 끝 문자에 주목
        
        while (txt.charAt(pt) == pat.charAt(pp)) {
          if (pp == 0)
            return pt; // 검색 성공
          pp--;
          pt--;
        }
        pt += (skip[txt.chatAt(pt)] > patLen - pp) ? skip[txt.charAt(pt)] : patLen - pp;
      }
      return -1; // 검색 실패
    }