部分匹配值(核心)
先列个求部分匹配值demo便于理解
//寻找待匹配串的部分匹配值,放在next数组中
public static int[] getNext(String dest) {
//创建一个next数组保存部分匹配值
int[]next=new int[dest.length()];
next[0]=0;//如果字符串长度为1 部分匹配值为0
for(int i=1,j=0;i<dest.length();i++){
//当dest.charAt(i) != dest.charAt(j)我们需要从next[j-1]获取新的j
//直到dest.charAt(i)==dest.charAt(j)成立才退出
//这是kmp算法的核心点
while(j>0 && dest.charAt(i) != dest.charAt(j)){
j=next[j-1];
}
//当满足下列条件时,部分匹配值就是+1
if(dest.charAt(i)==dest.charAt(j)){
j++;
}
next[i]=j;
}
return next;
}
真正KMP实现
/**
*
* @param s1 待匹配的串
* @param s2 匹配串
* @param next 存放部分匹配值的数组
*/
public static void getIndex(String s1,String s2,int[]next){
for(int i=0,j=0;i<s1.length();i++){
while(j>0 && s1.charAt(i)!=s2.charAt(j)){
j=next[j-1];
}
//如果被匹配字符串s1和匹配字符串s2对应,j++,如果j=s2.length()则匹配成功
if(s1.charAt(i)==s2.charAt(j)){
j++;
}
if(j==s2.length()){
System.out.println("匹配到的字符串下标为"+(i-j+1));
}else{
System.out.println("未匹配到");
}
}
}
总结:
其实KMP核心算法最难理解的地方在于部分匹配值的求解,匹配值为字符串前缀子集中和后缀子集中相同的个数,例如:abcab的前缀子集为a,ab,abc,abca;后缀子集为b,ab,cab,bcab;而此时部分匹配值最多为1因为只有ab=ab,而匹配值数组为next[]={0,1,0,0,0},部分匹配值的作用在于匹配的时候,待匹配串直接往后跳转匹配串的匹配值个数。而不用一一对比,相当于匹配串中已经匹配的值不在匹配