KMP瀛椾覆鍖归厤-鍏ラ棬

1銆佷覆鐨勫畾涔�

杩欓噷鎵�璇寸殑涓叉寚鐨勬槸瀛椾覆锛屽氨鏄瓧绗︿覆锛屽綋鐒朵笉鏄儳鐑や覆銆傝绠楁満鐨勫瓧涓叉槸鐢ㄧ紪鐮佸舰寮忎繚瀛樼殑锛岄�氬父鐨凙SCII鐮侊紝Unicode缂栫爜锛屼腑鏂囩殑GBK绛夌瓑銆傚浜庝竴涓瓧涓诧紝瀹氫箟涓�s="a1a2a3....an"锛岀浉搴旂殑瀵逛簬鍙︿竴涓瓧涓�t=b1b2b2b3....bm锛屽綋涓斾粎褰搉=m锛屼笖a1=b1,a2=b2,a3=b3....,an=bm锛屽垯涓や覆鐩哥瓑銆傚悓鏃讹紝褰撴弧瓒冲涓嬫潯浠舵椂s锛�

  1. n< m 锛� 涓攁1=b1(i=1,2,3....n)锛�
  2. 鏈塳<=min(m,n)锛屼娇ai=bi(i=1,2,3,4,5...k-1)锛宎k

2銆佹湸绱犵殑妯″紡鍖归厤绠楁硶

妯″紡鍖归厤鏈�鍏堣兘鎯冲埌鐨勫氨鏄湪涓�鐗囨枃绔犱腑鎵惧埌鎸囧畾鐨勫崟璇嶏紝濡傛枃鏈殑妫�绱紝寮曠敵鍒板崟璇嶇殑缁熻銆傛垜浠渶绠�鍗曟兂鍒扮殑灏辨槸灏嗘潗鏂欐枃鏈綋鍋氫竴涓緢闀跨殑涓诧紝鐒跺悗鐢ㄥ搴旂殑鍗曡瘝鍘诲尮閰嶏紝鍏蜂綋鏄寜鐓у崟璇嶇殑瀛楃涓�涓釜鍖归厤锛屽鏋滃尮閰嶅埌锛岀户缁紝鐩村埌鍗曡瘝灏鹃儴锛岃繖鏄渶鐞嗘兂鐨勬儏鍐碉紝鍚﹀垯锛屽崟璇嶉瀛楃鍐嶅幓姣旇緝鏂囨湰绗簩涓瓧绗︼紝渚濇鐩村埌鑾峰緱缁撴灉銆傚綊绾冲涓嬶細

  1. 鍖归厤鍒帮紝妫�绱㈣瘝锛屾枃鏈覆鍚屾椂鎺ㄨ繘锛�
  2. 鏈尮閰嶅埌锛屾绱㈣瘝鍐嶅幓鎵ц1锛屼粠鏂囨湰涓蹭笂娆″尮閰嶇殑涓嬩竴涓瓧绗﹀紑濮嬶紱
    鏈寸礌妯″紡鍖归厤绠楁硶鐨勬椂闂村鏉傚害涓烘渶濂戒负锛屾渶宸槸
    浠g爜濡備笅
    c++
//涓嶅瓨鍦ㄥ尮閰嶏紝杩斿洖0锛岄暱搴﹀瓨鍦╰[0],s[0]
//s 寰呭尮閰嶏紝t鍖归厤瀛椾覆
//t 涓嶇┖
int index(String s, String t, int pos){
int i = pos;
int j = 1;
while( i <= s[0] && j <= t[0]){
      if(s[i] == t[j]){
            ++i;
            ++j;  
      }else{
        i = i - j + 2;  //浠庝笅涓�涓綅缃紑濮�
        j = 1;  //鍥炲埌棣栦綅姣旇緝
      }
  }
   if( j > t[0]){
      return i - t[0];
    }else{
      return 0;
    }
} 

java

public class StringPattern {
    public static void main(String[] args) {
        String s = "dsfandkfnadsognoadsngasfsdbvonasdobvnadsodfnasonfo3n2n";
        String p = "";
        System.out.println(index(s, p));
    }

    private static int index(String s, String p) {
        if (s == null || p == null || "".equals(p)) {
            return -1;
        }
        int i = 0, j = 0;
        while (i < s.length() && j < p.length()) {
            if (s.charAt(i) == p.charAt(j)) {
                i++;
                j++;
            } else {
                i = i - j + 1;
                j = 0;
            }
        }

        if (j >= p.length()) {
            return i - j;
        }

        return -1;
    }
}

3銆並MP妯″紡鍖归厤

KMP绠楁硶鏄疍.E.Knuth銆丣.H.Morris浠ュ強V.R.Pratt鐨勫彂鏄庯紝鍙互閬垮厤閲嶅閬嶅巻鐨勭畻娉曪紝澶уぇ鎻愰珮鍖归厤鏁堢巼銆侹MP鏈変簺闅句互鐞嗚В锛岃繖绉嶇畻娉曟槸鍏稿瀷鐨勯�氳繃瀵瑰瑙傝寰嬬殑鎬荤粨锛屾潵褰掔撼鍑轰竴涓悎鐞嗙殑绠楁硶锛屽啀閫氳繃缂栫▼瀹炵幇鍜屼紭鍖栫殑缁撴灉銆傛垜浠湅鍒扮殑鍙湁鍒嗘瀽杩囩▼鍜岀畻娉曠粨鏋滐紝骞跺杩欎釜缁撴灉鍔犱互杩愮敤銆傛垜灏介噺绠�娲佺殑鏉ヨ〃杩拌繖涓畻娉曪紝浼氬涓�浜涢毦鐐硅繘琛岄噸鐐瑰己璋冨拰瑙i噴銆傛湰鏂囨槸KMP鐨勫垵绾т粙缁嶏紝鍚庨潰浼氫笓闂ㄤ粙缁岾MP鐨勪紭鍖栨柟妗堛��

3.1 KMP鍘熺悊

棣栧厛鐪嬩笅鏈寸礌鍖归厤鍙互浼樺寲鐨勭偣銆備緥濡傦細鍦�S=abcdefgab涓尮閰�T=abcdex锛屾湸绱犵畻娉曢鍏堜粠a涓�鐩村尮閰嶅埌f-x,绗�6浣嶃�傜劧鍚庝笅娆″尮閰嶅啀浠嶵-a鍘诲尮閰峉-b锛屼竴鐩村埌T-a鍖归厤S-c锛屼竴鐩村埌鍐嶅尮閰嶅埌S-f,T-a銆傞噸鐐癸細杩欓噷鎴戜滑鑳藉鍙戠幇锛屽瓧涓睺涓紝棣栧瓧姣峚涓庝粬涔嬪悗鐨勫瓧绗﹂兘涓嶇浉绛夛紝鍥犳涔嬪悗鍏充簬T-a鍜孲涓殢鍚庡瓧绗︾殑姣旇緝娌℃湁蹇呰杩涜锛岃繖鏄洜涓哄湪绗竴娆℃瘮杈冨氨鐭ラ亾S涓線鍚庣殑閮芥槸涓嶇瓑鐨勩�傛帹鐞嗗涓嬶細

鍥剧ず

KMP瀛椾覆鍖归厤-鍏ラ棬_第1张图片
KMP鍖归厤1

鐢变簬鎴戜滑寰楀埌杩欑缁忛獙锛屽鏋滃尮閰嶇殑涓睺鍜岀洰鏍囦覆S鏈夎繛缁浉鍚岀殑鍏冪礌锛屽垯璺宠繃姣旇緝锛屼笖杩欑鎯呭喌浼氬鑷碩涓璲鍊肩殑鍙樺寲銆傛墍浠ュ浜庡彟涓�绉嶆儏鍐靛 S=abcabaabca, T=abcabx锛岀敱浜嶵=(ab)c(ab)x锛岃繖閲岀涓�娆=1锛屽悗闈鐩存帴涓�3锛屽嵆姣旇緝鍒癱鐨勪綅缃紝j鐨勫彇鍊艰〃绀轰簡褰撴湡瀛楃涔嬪墠鐨勪覆鍦ㄤ覆涓殑鐩镐技搴︼紝鐩镐技搴﹁秺楂橈紝j瓒婂ぇ銆傛垜浠皢T鍚勪釜浣嶇疆涓妀鍊肩殑鍙樺寲琛ㄧず涓轰竴涓猲ext鐨勬暟缁勪繚瀛橈紝鎶借薄鎴愬嚱鏁拌〃绀轰负锛�
next[j] = \begin{equation} \begin{cases} 0锛宩=1\\ \max\{k|1<k<j\}锛屼笖p_1...p_{k-1}=p_{j-k+1}...p_{j-1}锛岃〃绀烘湁鐩稿悓瀛椾覆锛屽瓨鍦╬1=p4锛屽�间负k闆嗗悎鏈�澶у�糪\ 1 , 鍏朵粬鎯呭喌 \end{cases} \end{equation}

3.2 next鏁扮粍鎺ㄧ悊鍜屼娇鐢�

  1. T=abcdex
    j=1锛宯ext[1]=0锛沯=2锛屽瓙涓蹭负a锛屽叾浠栨儏鍐祅ext[2]=1锛涘綋j=3锛屽瓙涓瞐b锛宎!=b锛屾寜鍏紡涓哄叾浠栨儏鍐碉紝next[3]=1锛屾渶缁堢殑缁撴灉next[j]=011111
  2. T=abcabx
    j=1锛宯ext[1]=0锛沯=2锛宯ext[2]=1锛屽叾浠栨儏鍐碉紱j=3锛屽瓙涓瞐b锛宎!=b锛屽叾浠栨儏鍐�,next[3]=1锛沯=4锛屽瓙涓瞓c锛宐!=c锛屽叾浠栨儏鍐�,next[4]=1锛沯=5锛屽瓙涓瞐bca锛宎鍜岀鍚庝竴涓猘鐩稿悓锛屼笖鏈塸1pk-1=p5-k+1p5-1锛屾湁p1=p4锛屽洜姝=2锛宯ext[5]=3;褰搄=6锛屽瓙涓�(ab)c(ab)锛屾湁棣朼b=灏綼b锛宲1p2=p4p5鍗硃1pk-1=p6-k+1p5锛屽緱鍒皀ext[6]=3
    鍥犳寰楀埌锛屾敞鎰忎竴涓緥瀛愪腑k鍊煎彇鏈�缁堟渶澶х殑鍊笺��

KMP鐨勬椂闂村鏉傚害涓�锛屽拰鏈寸礌妯″紡鍖归厤鏈�濂界殑鎯呭喌涓�鑷淬��

3.3 绠楁硶瀹炵幇

c++

//鑾峰彇鍖归厤涓瞡ext鏁扮粍
void get_next(String t, int *index){
  int i,j;
  i=1;
  j=0;
  next[1]=0;
  while( i < t[0]) {
     if( j==0 || t[i] == t[j]){
         ++i;
         ++j;
         next[i] = j;
     }else{
       j = next[j];//娌℃湁鐩稿悓锛宩淇濇寔鍓嶅��
    }    
  }

}


int index_kmp(String s ,String t, int pos){
    int i = pos;
    int j = 1;
    int next[255];
    get_index(t,next);
     while(i t [0]){
       return i - t[0];
    return 0;
}

鍙互鐪嬪埌鍜屾湸绱犵畻娉曞樊鍒笉澶э紝涓昏鍦ㄤ簬next鏁扮粍鐨勫尯鍒�
java

public class StringPattern {
    public static void main(String[] args) {
        String s = "abcdexfgab";
        String p = "exf";

        System.out.println(index(s, p));
        System.out.println(indexKmp(s,p));
    }

    private static int index(String s, String p) {
        if (s == null || p == null || "".equals(p)) {
            return -1;
        }
        int i = 0, j = 0;
        while (i < s.length() && j < p.length()) {
            if (s.charAt(i) == p.charAt(j)) {
                i++;
                j++;
            } else {
                i = i - j + 1;
                j = 0;
            }
        }

        if (j >= p.length()) {
            return i - j;
        }

        return -1;
    }


    private static int indexKmp(String s, String p) {
        if (s == null || p == null || "".equals(p)) {
            return -1;
        }
        int i = 0, j = 0;
        int[] next = nextArray(p);
        while (i < s.length() && j < p.length()) {
            if (j == -1 || s.charAt(i) == p.charAt(j)) {
                i++;
                j++;
            } else {
                j = next[j];
            }
        }

        if (j >= p.length()) {
            return i - j;
        }

        return -1;
    }

    private static int[] nextArray(String p) {
        int[] next = new int[p.length()];
        int j = 1;
        int k = -1;
        next[0] = -1;
        while (j < p.length() - 1) {
            if (k == -1 || p.charAt(j) == p.charAt(k)) {
                ++j;
                ++k;
                next[j] = k;
            }else {
                k = next[k];
            }
        }
        return next;
    }
}
KMP瀛椾覆鍖归厤-鍏ラ棬_第2张图片
淇濇姢瑙嗗姏

你可能感兴趣的:(KMP瀛椾覆鍖归厤-鍏ラ棬)