Sample Input
3
BAPC
BAPC
AZA
AZAZAZA
VERDI
AVERDXIVYERDIAN
Sample Output
1
3
0
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<set>
#include<cstdlib>
#define ll long long
#define mem(a,x) memset((a),(x),sizeof ((a)))//x只能是0或-1
#define debug(x) cout<<"X: "<<(x)<<endl
#define de cout<<"************"<<endl
#define lowbit(x) ((x)&(-x))
#define lson rt<<1
#define rson rt<<1|1
#define gcd(a,b) __gcd(a,b)
#define lcm(a,b) a*b/(__gcd(a,b))
#define inf 0x3f3f3f3f//1e9+6e7
#define eps 1e-8
#define mod 1e9+7
#define N 1000010
const double pi=acos(-1.0);
using namespace std;
char S[N]; //主串
char T[N]; //模式串
int slen,tlen,ans;
int Next[N];
void getNext()
{
int i=0,j=-1;
Next[0]=-1;
while(i<tlen)
{
if(j==-1||T[i]==T[j])
Next[++i]=++j;
else
j=Next[j];
}
}
int KMP_Index()
{
int i=0,j=0;
getNext();
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 ret=0,i,j=0;
if(slen==1&&tlen==1)
{
if(S[0]==T[0])
return 1;
else
return 0;
}
getNext();
for(i=0;i<slen;i++)
{
while(j>0&&S[i]!=T[j])
j=Next[j];
if(S[i]==T[j])
j++;
if(j==tlen)
{
ret++;
//j=i+1; //如果求主串中包含几个模式串 j=i+1
j=Next[j];//如果求模式串在主串中出现的次数 j=Next[j]
}
}
return ret;
}
int main()
{
int TT;
cin>>TT;
while(TT--)
{
memset(S,0,sizeof S);//主串
memset(T,0,sizeof T);//模式串
cin>>T>>S;
tlen=strlen(T);
slen=strlen(S);
//复杂度:O(n+m)
//cout<<KMP_Index()<<endl; //模式串T在主串S中首次出现的位置,如果不存在,则输出-1
cout<<KMP_Count()<<endl; //模式串T在主串S中出现的次数或主串中包含几个模式串
}
return 0;
}
Sample Input
2
13 5
1 2 1 2 3 1 2 3 1 3 2 1 2
1 2 3 1 3
13 5
1 2 1 2 3 1 2 3 1 3 2 1 2
1 2 3 2 1
Sample Output
6
-1
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<set>
#include<cstdlib>
#define ll long long
#define mem(a,x) memset((a),(x),sizeof ((a)))//x只能是0或-1
#define debug(x) cout<<"X: "<<(x)<<endl
#define de cout<<"************"<<endl
#define lowbit(x) ((x)&(-x))
#define lson rt<<1
#define rson rt<<1|1
#define gcd(a,b) __gcd(a,b)
#define lcm(a,b) a*b/(__gcd(a,b))
#define inf 0x3f3f3f3f//1e9+6e7
#define eps 1e-8
#define mod 1e9+7
#define N 1000010
const double pi=acos(-1.0);
using namespace std;
int S[N]; //主串
int T[N]; //模式串
int slen,tlen,ans;
int nxt[N];
void getNext()
{
int i,j;
i=0;j=-1;nxt[0]=-1;
while(i<tlen)
{
if(j==-1||T[i]==T[j])
nxt[++i]=++j;
else
j=nxt[j];
}
}
int KMP_Index()
{
int i=0,j=0;
getNext();
while(i<slen&&j<tlen)
{
if(j==-1||S[i]==T[j])
{
i++;
j++;
}
else
j=nxt[j];
}
if(j==tlen)
return i-tlen;
else
return -1;
}
int KMP_Count()
{
int ret=0;
int i,j=0;
if(slen==1&&tlen==1)
{
if(S[0]==T[0])
return 1;
else
return 0;
}
getNext();
for(i=0;i<slen;i++)
{
while(j>0&&S[i]!=T[j])
j=nxt[j];
if(S[i]==T[j])
j++;
if(j==tlen)
{
ret++;
//复杂度:O(n+m)
//j=i+1; //如果求主串中包含几个模式串 j=i+1
j=nxt[j];//如果求模式串在主串中出现的次数 j=nxt[j]
}
}
return ret;
}
int main()
{
int TT;
cin>>TT;
while(TT--)
{
memset(S,0,sizeof S);//主串
memset(T,0,sizeof T);//模式串
cin>>slen>>tlen;
for(int i=0;i<slen;i++)
scanf("%d",&S[i]);
for(int i=0;i<tlen;i++)
scanf("%d",&T[i]);
ans=KMP_Index(); //模式串T在主串S中首次出现的位置,如果不存在,则输出-1
if(ans==-1)
cout<<-1<<endl;
else
cout<<ans+1<<endl;
}
return 0;
}
另外,可以通过next数组判断一个字符串是不是循环串(如abcabcabc)
如果next数组满足下面这个条件的话,表明是循环串:len%(len-nxt[len])==0
其中len是字符串的长度,len-nxt[len]是循环节的长度,len/(len-nxt[len])是循环的次数。