1题意。
求目标串中有多少个位置可重叠的子串。
2分析。
裸的kmp。
3代码
//在目标串中找有多少个子串,出现的子串在位置上上可以交叠
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
const int w_maxn=10010;
const int t_maxn=1000010;
char word[w_maxn];//模式串Patterm
char text[t_maxn];//目标串Target
int next[w_maxn];
int sum,w_len,t_len;
void Get_next(){
memset(next,0,sizeof(next));
next[0]=-1;
int k=-1,i=0;
while(i<=w_len){ ///Note: is == w_len !!(否则匹配成功后,无法跳next[w_len]
if(k==-1||word[i]==word[k])
next[++i]=++k;
else
k=next[k];
}
return ;
}
void Kmp(){
int i,k,his_i;// his_i (s.t. history_i)
sum=i=k=his_i=0;// k next[] ; i text[]
while(i<t_len&&k<w_len){
if(k==-1||text[i]==word[k]){
i++;k++;
}
else
k=next[k];
if(k==w_len){
sum++;
//i++;之前已经i++过了
k=next[k];//k=0;不能跳到最开始,只需要跳到上一个即可
}
}
}
int main()
{
int kk;
scanf("%d",&kk);
while(kk--){
scanf("%s%s",word,text);
w_len=strlen(word),t_len=strlen(text);
Get_next();
//for(int i=0;i<=w_len;i++) cout<<"-"<<next[i];
Kmp();
cout<<sum<<endl;
}
}