zoukankan      html  css  js  c++  java
  • POJ 2752 Seek the Name, Seek the Fame(KMP中next的理解)题解

    题意:

    要求你给出每个前后缀相同的串的长度,比如: "alala"的前缀分别为{"a", "al", "ala", "alal", "alala"}, 后缀分别为{"a", "la", "ala", "lala", "alala"}. 其中有{"a", "ala", "alala"}是相同的,所以答案是1,3,5。

    链接

    思路:

    本题需要灵活运用next数组,要理解next的含义才能做。

    next[i]代表长度为i的子串的前后缀匹配值,我们需要先求出当前主串的最大匹配度k,也就是前k个和后k个一样。然后我们怎么得到s[1...k-1]和s[len-k+2...len]是否相等(这里的数字不是下标),即前k-1个和后k-1个怎么比较是否相同。这里就需要深入理解next了。我们得到了k那么next[next[k]]代表着前k个的前缀和后k个的后缀的最大匹配度,然后如此递归即可得到答案。这里建议画图理解一下

    代码:

    #include<iostream>
    #include<algorithm>
    const int N = 400000+5;
    const int INF = 0x3f3f3f3f;
    using namespace std;
    int fail[N],ans[N];
    char p[N];
    void getFail(){
         fail[0] = -1;
         int j = 0,k = -1;
         int len = strlen(p);
         while(j <= len){
            if(k == -1 || p[j] == p[k]){
                fail[++j] = ++k;
            }
            else{
                k = fail[k];
            }
         }
    }
    /*int KMP(){
        int num = 0;
        getFail();
        int i = 0,j = 0;
        int lent = strlen(t),lenp = strlen(p);
        while(i < lent){
            if(j == -1 || t[i] == p[j]){
                i++;
                j++;
                if(j == lenp) num++;
            }
            else{
                j = fail[j];
            }
        }
        return num;
    }*/
    int main(){
        int cnt,Case = 1;
        while(scanf("%s",p) != EOF){
            getFail();
            cnt = 1;
            int len = strlen(p);
            ans[0] = len;   //本身肯定是
            len = fail[len];   //最大前后缀匹配值
            while(fail[len] >= 0){
                ans[cnt++] = len;
                len = fail[len];
            }
            for(int i = cnt - 1;i >=0;i--){
                if(i != cnt-1) printf(" ");
                printf("%d",ans[i]);
            }
            printf("
    ");
        }
        return 0;
    }
    


  • 相关阅读:
    BZOJ2435 NOI2011道路修建
    BZOJ2431 HAOI2009逆序对数列(动态规划)
    BZOJ2456 mode
    BZOJ2324 ZJOI2011营救皮卡丘(floyd+上下界费用流)
    BZOJ2303 APIO2011方格染色(并查集)
    BZOJ2299 HAOI2011向量(数论)
    BZOJ2169 连边(动态规划)
    BZOJ2159 Crash的文明世界(树形dp+斯特林数)
    洛谷 P1306 斐波那契公约数 解题报告
    洛谷 P2389 电脑班的裁员 解题报告
  • 原文地址:https://www.cnblogs.com/KirinSB/p/9408773.html
Copyright © 2011-2022 走看看