题意
给定一个单词和一个字符串,求单词在字符串中出现的次数
思路
将单词当作模式串求 next(文中用 nxt 表示),把包含模式串最后一个字母所对应的前后缀也求出来(如果有n个字符则求到nxt[n]),根据最后的这个 nxt[n] 的值我们将知道与模式串相同的前缀在文本串的下一个位置。
AZA
AZAZAZA
AZA的nxt值为:
-1 0 -1 1
当第一次匹配完时,j=next[j]=next[3]=1; 所以文本串中a[3]=' Z ' 此时就应该匹配模式串中的b[1]=' Z '了
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1000010;
int nxt[maxn];
char a[maxn],b[maxn];
int k;
void getnext()
{
int i,j;
i = 0;
j = nxt[0] = -1;
int n = strlen(a);
while(i<n)
{
if(j==-1 || a[i]==a[j])
{
i++,j++;
if(a[i]!=a[j])
nxt[i] = j;
else
nxt[i] = nxt[j];
}
else
j = nxt[j];
}
}
void Search()
{
int i,j;
i = j = 0;
int n = strlen(a);
int m = strlen(b);
while(i<m && j<n)
{
if(j==-1 || a[j]==b[i])
{
i++,j++;
if(j==n)
{
k++;
j = nxt[j];
}
}
else
j = nxt[j];
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
k = 0;
scanf("%s",a);
scanf("%s",b);
getnext();
Search();
printf("%d\n",k);
}
return 0;
}