题目大意:
多组测试数据,每组测试数据两个字符串,让你找出一个字符串里有多少另一个字符串。
分析:
应该就是kmp的魔板题,但是可能是因为我kmp掌握的不好吧,卡了好久好久。
这里一个比较巧妙地思维转换就是,在找到一个模板串之后,ans++,如何寻找下一个,这个事情就可以很巧妙地看成是模板串的最后一个字母之后还有一个假想的与之前任何一个字符串都不同的字符,这个字符当然也不可能和原字符串的任何一个匹配成功了,也就是说如果在这个假想的最后一个字符串的位置匹配失败,那么就计数+1,然后继续按照匹配失败的情况接着继续进行。
代码:
#include<iostream>
#include<stdio.h>
#include<string.h>
#define maxm 10500
#define maxn 1000500
using namespace std;
int next[maxm]={0};
char model[maxm]={0};
char a[maxn];
int test;
void my_next()
{
int j=-1;int k=0;
next[0]=-1;
int n=strlen(model);
while(k<n)
{
if(j!=-1&&model[j]!=model[k])
{
j=next[j];continue;
}
j++;k++;
if(model[j]==model[k])next[k]=next[j];
else next[k]=j;
//cout<<"next["<<k<<"]="<<next[k]<<" ";
}
return;
}
void ceshi1()
{
for(int i=0;i<strlen(model);i++)
{
cout<<next[i]<<" ";
}
cout<<endl;
}
/*
int my_kmp()
{
int j=0;
int s=0;
int n=strlen(a);int m=strlen(model);
for(int i=0;i<n;i++)
{
if(j==m)
{
i=i-m+1;
j=0;
s++;
}
if(model[j]==a[i])j++;
else
{
if(next[j]==-1)j=0;
else
{
j=next[j];i--;
}
}
}
return s;
}
*/
/*int my_kmp()
{
int s=0;
int i=0,j=0;//i指向model,j指向a;
int n=strlen(a),m=strlen(model);
for(j=0;j<n;)
{
//cout<<j;
if(a[j]==model[i])
{
i++;j++;
if(i>=m)
{
s++;
if(j>=n)return s;
i=0;j=j-m+1;
}
continue;
}
//cout<<"po";
j=j-next[i];
i=0;
}
return s;
}
*/
int my_kmp()
{
int ans = 0;
int plen = strlen(model);
int tlen = strlen(a);
int i = 0, j = 0;
while (i < tlen)
{
if (j == -1 || model[j] == a[i])
{
i++;
j++;
}
else
{
j = next[j];
}
if (j == plen)
{
ans++;
//cout<<next[j]<<" "<<j<<" ";
j = next[j];
}
}
return ans;
}
int main()
{
cin>>test;
while(test--)
{
scanf("%s",model);
scanf("%s",a);
my_next();
cout<<my_kmp()<<endl;
//ceshi1();
//next2(model);
//ceshi1();
/*memset(a,0,sizeof(a)); memset(model,0,sizeof(model));*/
}
}