这道题目和hdu2087差不多,都是求匹配数,但是又有点不同,不同点在于,当找到一个匹配后,HDU 2087是一定要从该主串匹配后一位开始进行匹配,而HDU 1686
则不同,是匹配后,然后可以从已经匹配好的字符串中开始进行匹配!
HDU 1686代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn1=10005;
const int maxn2=1000005;
int next1[maxn1];
char s1[maxn2],s2[maxn2];
int lent,lens;
void getnext(char s1[],int lent)
{
int j=0,k=-1;
next1[0]=-1;
while(j<lent)
{
if(s1[j]==s1[k]||k==-1)
next1[++j]=++k;
else
k=next1[k];
}
}
int KMP(int lent,int lens)
{
int i=0,j=0,sum=0;
while(i<lens)
{
if(j==lent)
{
sum++;
j=next1[j];//这里和下面不同!!!
}
if(s2[i]==s1[j]||j==-1)
++i,++j;
else
j=next1[j];
}
if(j==lent)sum++;
return sum;
}
int main()
{
int t;
scanf("%d",&t);
getchar();
for(int i=0; i<t; i++)
{
gets(s1);
gets(s2);
lent=strlen(s1);
lens=strlen(s2);
getnext(s1,lent);
int ans;
ans=KMP(lent,lens);
printf("%d\n",ans);
}
return 0;
}
HDU 2087代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=1005;
char s[maxn],t[maxn];
int next1[maxn];
int lent,lens;
void getnext()
{
int j=0,k=-1;
next1[0]=-1;
while(j<lent)
{
if(t[j]==t[k]||k==-1)
next1[++j]=++k;
else
k=next1[k];
}
}
int KMP()
{
getnext();
int i,j;
int sum;
i=0;j=0;sum=0;
while(i<lens)
{
if(j==lent)sum++,j=0;//就是这里不同!
if(s[i]==t[j]||j==-1)
i++,j++;
else
j=next1[j];
}
if(j==lent)sum++;
return sum;
}
int main()
{
while(scanf("%s",s),s[0]!='#')
{
scanf("%s",t);
lens=strlen(s);
lent=strlen(t);
printf("%d\n",KMP());
}
return 0;
}