KMP算法的做用在於在一個主串中查找一個主串。算法
傳統查找子串的方法是一個字符一個字符的比較,代碼以下:數組
public static int notKMP(String main,String sub){ for (int i=0;i<main.length();i++){ int j=0; int k=i; while (main.charAt(k)==sub.charAt(j)){ k++; j++; if (j==sub.length()){ return i; } } } return -1; }
這種方式在遇到不相同的時候,主串往下移動一位,子串恢復到0.繼續的進行對比。
spa
KMP的算法的有點在於子串中若是有相同的部分的話,那麼能夠省略一部分的校驗,下面這個圖加深一些印象:code
若是咱們使用KMP算法的話,那麼中間的紅框的那部分是不須要比較的,很顯而易見,由於他們都第一步進行了比較了,固然怎麼判斷仍是須要算法的。blog
算法的步驟分爲兩部分,第一部分是算出子串的next數組,這個數組表達的就是子串的類似度,具體算法實現:get
/** * 返回KMP數組 * @param str * @return */ public static int[] getNextArr(String str){ int[] nexts=new int[str.length()]; //j=1 的時候爲0 j=2的時候爲1 nexts[0]=0; nexts[1]=1; for (int j=2;j<str.length();j++){ int index=1; for (int i=0;i<j-1;i++){ if(str.substring(0,i+1).equals(str.substring(j-i-1,j))){ index++; } } nexts[j]=index; } return nexts; }
第二部分就是進行匹配:string
/** * * @param s 主串 * @param t 子串 * @param pos 從主串哪一個位置開始匹配 * @return */ public static int indexKMP(String s,String t,int pos){ int i=pos; int j=0; int[] nexts=getNextArr(t); while (i<s.length()&&j<t.length()){ if (j==0||s.charAt(i)==t.charAt(j)){ i++; j++; }else { j=nexts[j-1]; } } if (j>=t.length()){ return i-t.length(); } return 0; }
. 總的來說就是隻關注子串,出現相同的那部分能夠不進行比較。class