感谢队友hupo3412提供的模板
nxt数组:最长前缀后缀匹配长度
简易算法思路:对大串每个下标i,小串下标j从0开始,一个个匹配,若匹配成功:i++,j++
匹配失败j返回上一nxt[j]而不是回到0,直到匹配为止
所以我们只要预先维护出nxt即可
java:
static int[] kmpPre(char x[],int n){//by hupo3412
int i=0,j=-1;
int nxt[]=new int[n+5];
int fail[]=new int[n+5];
nxt[0]=fail[0]=-1;
while (i<n){
while (j!=-1&&x[i]!=x[j])j=fail[j];//不能匹配往前找最长适配
i++;j++;
nxt[i]=fail[i]=j;//若匹配,最长前后缀长度 能加1
//路径压缩,可加可不加
if(i<n&&x[i]==x[j])fail[i]=fail[j];
}
return fail;
}
static int kmpCount(char x[],int m,char y[],int n){//x是小串 y是大串
int ans=0,i=0,j=0;
int fail[]=kmpPre(x,m);
while(i<n){
while(j!=-1&&x[j]!=y[i])j=fail[j];
i++;j++;
if(j>=m){
ans++;
j=fail[j];
}
}
return ans;
}