//poj 3461 kmp
//1420 KB 125 ms G++
#include <cstdio>
#include <cstring>
using namespace std;
int next[10005],len1,len2;
char s[1000005],mod[10005]; //s是主串,mod是模式串
int getnext() //求next数组,next数组用来当匹配不相同时,不必返回首个字母进行匹配,可以节省时间复杂度
{
int i,j=0; //i相当于每一个字母的下标,j表示与mod[i]进行匹配的字母下标
next[1]=0; /*由于scanf("%s%s",mod+1,s+1); 表示从mod的第二个位置开始接收字符所以为next[1]
为什么等于0,比如abc abc ab 他的next值 我会标记成000 123 45,自己理解下*/
for(i=2;i<=len2;i++) /* 模式串从第二个字符开始计算next值,一个一个字符计算下去*/
{
while(j>0&&mod[j+1]!=mod[i]) //如果mod[i]!!=mod[j+1]则mod[i]和mod[next[j+1]]比较
j=next[j];
if(mod[j+1]==mod[i]) j++; //如果相等,则next值j++
next[i]=j; //为mod[i]赋next值
}
}
int kmp()
{
int i,j=0,k=0;
getnext();
for(i=1;i<=len1;i++)
{
while(j>0&&mod[j+1]!=s[i]) //用mod的next值去和s串的next值比较
j=next[j];
if(mod[j+1]==s[i]) //如果想当j就加1,相等就加1,不相等就回到mod[next[j]],next[j]也可以理解为
//前面有几个已经匹配,所以到j==len2时就可以判断为已经完成了一个匹配
{
j++;
if(j==len2) k++;
}
}
return k;
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
while(n--)
{
scanf("%s%s",mod+1,s+1);
len1=strlen(s+1);
len2=strlen(mod+1);
printf("%d\n",kmp());
}
}
return 0;
}
poj 3461
最新推荐文章于 2023-06-25 08:42:03 发布