//这个模板主串和模式串下标都是从0开始的
//next数组下标是从1开始的
char S[maxn],T[maxn];
int _next[maxn];
int slen,tlen;
//求模式串的next数组
void GetNext(){
int j=0,k=-1;
_next[0]=-1;
while(j<tlen){
if(k==-1||T[k]==T[j]){
_next[++j]=++k;
}else {
k=_next[k];
}
}
}
//求模式串在主串中第一次出现的下标,如果没出现返回-1
int Kmp_Index(){
GetNext();
int i=0,j=0;
while(i<slen&&j<tlen){
if(j==-1||S[i]==T[j]){
++i;
++j;
}
else j=_next[j];
}
if(j==tlen) return i-tlen;
else return -1;
}
//返回模式串在主串中出现的次数
int Kmp_Count(){
int ans=0,i=0,j=0;
if(slen==1&&tlen==1){
if(S[i]==T[j]) return 1;
else return 0;
}
/*找T串在S串中出现的次数,那么这个for循环就是循环的S串,
然后对于每一个S的下标,如果T的j位置和它不匹配,
那么就用一个while循环一直next下去好了,然后如果相等就加一,
如果j=tlen,就让ans++,然后j=next[j],找下个位置是不是和next[j]位置匹配*/
for(i=0;i<slen;i++){
while(j>0&&S[i]!=T[j]){
j=_next[j];
}
if(j==-1||S[i]==T[j]) ++j;
if(j==tlen){
++ans;
j=_next[j];
}
}
return ans;
}
char S[maxn],T[maxn];
int _next[maxn];
void GetNext(){
int j=0,k=-1;
_next[0]=-1;
while(j<tlen){
if(k==-1||_next[k]==_next[j]){
_next[++j]=++k;
}else {
k=_next[k];
}
}
}
int Kmp_Index(){
GetNext();
int i=0,j=0;
while(i<slen&&j<tlen){
if(j==-1||S[i]==T[j]){
++i;
++j;
}
else j=_next[j];
}
if(j==tlen) return i-tlen;
else return -1;
}
int Kmp_Count(){
int ans=0,i=0,j=0;
if(slen==1&&tlen==1){
if(S[i]==T[j]) return 1;
else return 0;
}
for(i=0;i<slen;i++){
while(j>0&&S[i]!=T[j]){
j=_next[j];
}
if(j==-1||S[i]==T[j]) ++j;
if(j==tlen){
++ans;
j=_next[j];
}
}
return ans;
}