一道KMP题目折腾了我一天了,开始的时候怎么也想不到和KMP有什么联系,看了网上的大神解法后恍然大悟,
题意是,给一串字符串,问这串字符串所有的前缀总共在这个字符串中出现了几次。
已经有了next数组,next[i]=j表示最大的j使得0~j==i-j~i,因此,对于样例abab,则有
0 1 2 3
b[ ] a b a b
p[ ] -1 -1 0 1
对于4个前缀:
a
ab
aba
abab
设dp[i]表示子串b[0~i]共含有以b[i]为结尾的前缀的数目,则以b[i]结尾的前缀数就是自己本身加上以b[p[i]]结尾的前缀数,也就是例如i=2
则有:
a
题意是,给一串字符串,问这串字符串所有的前缀总共在这个字符串中出现了几次。
已经有了next数组,next[i]=j表示最大的j使得0~j==i-j~i,因此,对于样例abab,则有
0 1 2 3
Problem : 3336 ( Count the string ) Judge Status : Accepted
RunId : 7164232 Language : C Author : freestyle4568
Code Render Status : Rendered By HDOJ C Code Render Version 0.01 Beta
# include<stdio.h>
# include<string.h>
int next[200003],dp[200003];
void getnext(char *str,int len)
{
int i,j;
for(i=1,next[0]=-1;i<=len;i++)
{
j=next[i-1];
while(j>0&&str[i]!=str[j+1])
j=next[j];
if(str[i]==str[j+1])
next[i]=j+1;
else
next[i]=0;
}
}
void main()
{
int i,len,sum,n;
char str[200003];
scanf("%d",&n);
while(n--)
{
scanf("%d%s",&len,str+1);
getnext(str,len);
for(i=1,sum=0,dp[0]=0;i<=len;i++)
{
dp[i]=dp[next[i]]+1;
sum=(sum+dp[i])%10007;
}
printf("%d\n",sum);
}
}
b[ ] a b a b
p[ ] -1 -1 0 1
对于4个前缀:
a
ab
aba
abab
设dp[i]表示子串b[0~i]共含有以b[i]为结尾的前缀的数目,则以b[i]结尾的前缀数就是自己本身加上以b[p[i]]结尾的前缀数,也就是例如i=2
则有:
a
aba这两个前缀,其中a就是b[p[i]]结尾的前缀。