提到字符串匹配不得不提到KMP算法,它將原有的字符串匹配算法的時間複雜度從O(N*M)縮減到O(N),
具體的思路先計算模式串的next[]數組值
next[i]含義表示next[0---i-1]數組中next[0----k]和next[k+1------i-1]成立的最大值,其中0=<k<i-1,默認next[0]=-1,next[1]=0
舉例說明:模式串“abcabcde”的next數組值爲{-1,0,0,0,1,2,3,0}
模式串中第三個字符‘c’ ,他的前綴字符“ab”中找不到next[0----k]和next[k+1------1]成立的值 ,則next[2]=0
模式串中第四個字符‘a’ ,他的前綴字符“abc”中不到next[0----k]和next[k+1------2]成立的最大值,則next[3]=0
模式串中第五個字符‘b’ ,他的前綴字符“abca”中next[0----k]和next[k+1------3]成立的最大值爲next[0]=next[3] ,則next[4]=1
模式串中第六個字符‘c’ ,他的前綴字符“abcab”中next[0----k]和next[k+1------4]成立的最大值next[0,1]=next[3,4],則next[5]=2
模式串中第七個字符‘d’ ,他的前綴字符“abcabc”next[0----k]和next[k+1------5]成立的最大值next[0,1,2]=next[3,4,5],則next[6]=3
模式串中第八個字符‘e’ ,他的前綴字符“abcabcd”中不到字符串匹配成立的值 ,則next[7]=0
package com.stone.Algothrim;
public abstract class KMPTest{
public static int getIndexOf(String s, String m) {
if (s == null || m == null || m.length() < 1 || s.length() < m.length()) {
return -1;
}
char[] ss = s.toCharArray();
char[] ms = m.toCharArray();
int si = 0;
int mi = 0;
int[] next = getNext(ms);
//結果爲:next = {-1,0,0,0,1};
while (si < ss.length && mi < ms.length) {
if(ss[si]==ms[mi]){
si++;mi++;
}else{
if(mi==0)
si++;
else
mi=next[mi];
}
}
return mi == ms.length ? si - mi : -1;
}
/**
* 獲得字符串的next函數值
* @param t 字符串
* @return next函數值
*/
public static int[] getNext(char[] ms) {
if (ms.length == 1) {
return new int[] { -1 };
}
int[] next = new int[ms.length];
next[0] = -1;
next[1] = 0;
int pos = 2;
int cn = next[1]; //表示第pos-1個字符的next[pos-1]值,即最長匹配個數
while (pos < next.length) {
if (ms[pos - 1] == ms[cn]) {
next[pos++] = ++cn;
} else {
if (cn == 0) {
next[pos++] = 0;
} else {
cn = next[cn];
}
}
}
return next;
}
public static void main(String[] args){
String str="afdasabcacafadsfasdf";
String match="abcac";
System.out.println(getIndexOf(str, match)); // KMP匹配字符串
}
}