得到next函数:覆盖函数(overlay_function)
覆盖函数所表征的是pattern本身的性质,可以让为其表征的是pattern从左开始的所有连续子串的自我覆盖程度。
比如如下的字串,abaabcaba
由于计数是从0始的,因此覆盖函数的值为0说明有1个匹配,对于从0还是从来开始计数是偏好问题,
具体请自行调整,其中-1表示没有覆盖,那么何为覆盖呢,下面比较数学的来看一下定义,比如对于序列
a0a1...aj-1 aj
要找到一个k,使它满足
a0a1...ak-1ak=aj-kaj-k+1...aj-1aj
而没有更大的k满足这个条件,就是说要找到尽可能大k,使pattern前k字符与后k字符相匹配,k要尽可能的大,
原因是如果有比较大的k存在,而我们选择较小的满足条件的k,
那么当失配时,我们就会使pattern向右移动的位置变大,而较少的移动位置是存在匹配的,这样我们就会把可能匹配的结果丢失。
http://acm.nyist.net/JudgeOnline/problem.php?pid=5练习。
#include<stdio.h>
#include<string.h>
int next[12];
void get_next(char *p,int len)
{
int j=1;
next[0]=-1;
int k=-1;
for(;j<len;j++)
{
while(k>-1&&p[k+1]!=p[j]) k=next[k];
if(p[k+1]==p[j]) k++;
next[j]=k;
}
}
int main()
{
freopen("Input.txt","r",stdin);
int ncase,i,j;
char s[1002],p[12];
scanf("%d",&ncase);
while(ncase--)
{
scanf("%s %s",p,s);
get_next(p,strlen(p));
int num=0;
i=0;j=-1;
while(i<strlen(s))
{
while(j>-1&&p[j+1]!=s[i]) j=next[j];
if(p[j+1]==s[i]) j++;
i++;
if(j==strlen(p)-1) { num++;j=next[j]; }
}
printf("%d\n",num);
}
return 0;
}