package algorithm;
/***
*
* @author mac
*
*/
public class KMPMatchPattern {
public static void main(String[] args) {
String source = "abababaababacb";
String target = "abaabab";
KMPMatchPattern p = new KMPMatchPattern();
//int[] ne = p.next("abababab");//你可以测试一下next方法
int test = "".indexOf("s");//你可以在eclipse里点击进入sun官方indexOf查看
System.out.println(test);
System.out.println(p.indexOf(source,target));
}
public int indexOf(String source,String target){
int[] next = next(target);//初始化得到next数组,以备后面使用
int index = -1;//为了没有找到子字符串时返回-1
int i=0,j = 0;//i指向原字符串(source),j指向要寻找的目标字符串(target)
while(i<source.length()&&j<target.length()){
if(source.charAt(i) == target.charAt(j)){//元素相等则i++,j++
i++;
j++;
}
else if(j == 0){//不匹配,而且是第一个位置就不匹配
i++;
}else{
j =next[j-1];//不匹配且不是第一个位置
}
}
if (j == target.length()){
return i - target.length();
}return index;
}
/***
* 为模式target字符串的每次分割产生max(前缀==后缀)的前缀最后一个位置的索引+1
* @param target 我要search查找的目标模式串
* @return 一个分割后按0,1,2索引分割的目标数组,里面分别存放的是分割1..n个子元素时的前缀最后一个位置的索引+1
*/
public int[] next(String target){
int[] next = new int[target.length()];
for(int i = 0;i<next.length;i++){
if(i == 0){
next[i] = 0;
}
else{
for(int j =1;j<=i;j++){
if(target.substring(0,j).equals(target.substring(i - j + 1,i+1))){//因为substring方法的第二参数不包含此索引,所以为最后一个索引位置+1
next[i] = j;
}
}
}
}
return next;
}
}
java源代码如上