Count the string(HDU3336)【KMP】

题库链接http://acm.hdu.edu.cn/showproblem.php?pid=3336 

  这道题是KMP的next数组的一个简单使用,首先要理解next数组的现实意义:next[i]表示模式串的前i个字符所组成的字符串的最长前缀后缀匹配长度,就比如对于字符串"abcdabe",它的next[3]=0,因为前三个字符构成的字符子串"abc"前后缀最长匹配长度为0,而next[6]=2,因为对于子串"abcdab",它的前缀后缀最大可以匹配出"ab",长度为2,对应了它的前缀后缀最大匹配长度。

  对于这道题,我们从1位置开始遍历整个next数组,首先每一个前缀串自身都对答案有1的贡献,所以首先ans++,此外,当与到next[i]数值大于0的位置,说明前i个字符组成的子串有大于零的前缀后缀匹配,即前缀串在该位置重复出现了一次,所以此时ans再加1。

 详见代码:

#include<bits/stdc++.h>

using namespace std;
char s[200010];
int t,n,nex[200010];
int ans;

void getNex(){
    nex[0]=-1;
    int k=-1,j=0;
    while(j<n){
        if(k==-1||s[j]==s[k]){
            ++j;++k;
                nex[j]=k;
        }
        else k=nex[k];
    }
}
int main(){
    scanf("%d",&t);
    while(t--){
        ans=0;
        scanf("%d%s",&n,s);
        getNex();
        for(int i=1;i<=n;i++){
            ans++;
            if(nex[i]!=0)
                ans++;
            ans%=10007;
        }
        printf("%d\n",ans);
    }
    return 0;
}
xxmlala-Code

  

posted @ 2019-08-29 20:45  xxmlala  阅读(122)  评论(0编辑  收藏  举报