好像一直没有看懂的样子,直到昨天晚上顿悟了!其实kmp与一般的最朴素匹配的想法一样只是他每一次失配后都不是从头开始,而是根据一定的规则来使子串t从失配的位置重新配;而失配的位置就是靠next数组来记录的。而next数组的求法主要是:在子串T内next[0]=-1;如果t[i]!=t[j],j=next[j],之后再继续比较;如果相等next[i]=j;而kmp的求法和next相近,只是比较的对象发生了变化由t[i]与t[j]比较变成s[i]与t[j]的比较;下面上代码:
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int maxn=1000005;
int ls,lt;
int Next[maxn];
char s[maxn],t[maxn];
inline void getNext()
{
int i,j=-1;
Next[0]=-1;
for(int i=1;i<lt;i++){
while(j!=-1&&t[i]!=t[j+1])j=Next[j];
if(t[i]==t[j+1])j++;
Next[i]=j;
}
}
inline int kmp()
{
getNext();
int i,j=-1,sum=0;
for(int i=0;i<ls;i++){
while(j!=-1&&s[i]!=t[j+1])j=Next[j];
if(s[i]==t[j+1])j++;
if(j==lt-1){
sum++;
j=Next[j];
}
}
return sum;
}
int main()
{
int cas;
scanf("%d",&cas);
while(cas--){
scanf("%s%s",t,s);
ls=strlen(s);
lt=strlen(t);
printf("%d\n",kmp());
}
return 0;
}