HDU_3336 Count the string(KMP)

来源:互联网 发布:淘宝店铺水印制作 编辑:程序博客网 时间:2024/06/05 06:15

题目请点我
题解:
题意是在确定了一个前串后,问能找到多少个与前串对应的后串。注意后串是可以重叠的,比如aaaaaa,若固定前串为aa,则后传为aaaa,共有三个与之匹配,所以共有四个aa字串。最开始的思路是枚举字串的长度,但是是O(N^2)的时间复杂度,超时了很多次。后来借鉴同学的方法,换了一种思路,每次利用while循环找到以A[i]结尾的长度不大于i/2的匹配子串。不考虑子串的长度,而是考虑共有多少个符合条件的子串。可以证明所有的子串都是唯一的,很好的方法。
代码实现:

#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#define MAX 200000using namespace std;int T;int N;int res;int len;char A[MAX];char B[MAX];int Next[MAX];void solve();void getnext(int x);const int mod = 10007;int main(){    scanf("%d",&T);    while( T-- ){        scanf("%d",&N);        getchar();        gets(A);        res = 0;        len = strlen(A);        getnext(len);        solve();        printf("%d\n",res);    }    return 0;}void solve(){    int j = 0;    for( int i = 1; i <= len; i++ ){        j = i;        //while 循环向前查找        while( Next[j] > 0 ){            if( Next[j]*2 < i+1 ){                res++;                res%=mod;            }            j = Next[j];        }    }    res = (res%mod+len%mod)%mod;    return ;}void getnext(int x){    memset(Next,0,sizeof(Next));    Next[0] = -1;    int i = 0, j = -1;    while( i < x ){        if( j == -1 || A[i] == A[j] ){            Next[++i] = ++j;        }        else{            j = Next[j];        }    }}
0 0
原创粉丝点击