zoukankan      html  css  js  c++  java
  • POJ2752题解——KMP入门

    题目链接:http://poj.org/problem?id=2752

    Seek the Name, Seek the Fame

    The little cat is so famous, that many couples tramp over hill and dale to Byteland, and asked the little cat to give names to their newly-born babies. They seek the name, and at the same time seek the fame. In order to escape from such boring job, the innovative little cat works out an easy but fantastic algorithm: 

    Step1. Connect the father's name and the mother's name, to a new string S. 
    Step2. Find a proper prefix-suffix string of S (which is not only the prefix, but also the suffix of S). 

    Example: Father='ala', Mother='la', we have S = 'ala'+'la' = 'alala'. Potential prefix-suffix strings of S are {'a', 'ala', 'alala'}. Given the string S, could you help the little cat to write a program to calculate the length of possible prefix-suffix strings of S? (He might thank you by giving your baby a name:) 

    Input

    The input contains a number of test cases. Each test case occupies a single line that contains the string S described above. 

    Restrictions: Only lowercase letters may appear in the input. 1 <= Length of S <= 400000. 

    Output

    For each test case, output a single line with integer numbers in increasing order, denoting the possible length of the new baby's name.

    Sample Input

    ababcababababcabab
    aaaaa
    

    Sample Output

    2 4 9 18
    1 2 3 4 5

    题目意思:就是给你一个字符串让你找出该字符串所有的相同的前后缀,把长度值按从小到大输出。
    题目思路:这不就是kmp的匹配过程嘛~~~理解了next数组就很好做。比如所我们的next[len-1]代表的意思就是s1[len-1]不匹配的时候他应该去的下一个位置,而根据s1[len-1]==s1[next[len-1]],则从0到s1[next[len-1]]和从s1[len-1-(next[len-1]+1)+1]到s1[len-1]是相同的(next长度不包括自己,也就是len)。
    然后一直用next的递归就好了,就能用next依次求出字符串最长相同前缀后缀的长度、字符串第二长相同前缀后缀的长度。。。(next下标+1即为长度)
    #include<stdio.h>
    #include<string.h>
    using namespace std;
    const int maxn=4e5+10;
    char s1[maxn];
    int next[maxn],count[maxn],cnt;
    void GetNext(char *p)
    {
        int plen=strlen(p);
        next[0]=-1;
        int k=-1;
        int j=0;
        while(j<plen)
        {
            if(k==-1||p[j]==p[k])
            {
                ++j;++k;
                next[j]=k;
            }
        else k=next[k];
        }
    }
    int main()
    {
        while(~scanf("%s",s1))
        {
            GetNext(s1);//求出next数组 
            cnt=0;
            int len=strlen(s1);
            int t=next[len-1];
            while(t!=-1)
            {
                if(s1[t]==s1[len-1])count[cnt++]=t+1;
                t=next[t];
            }
            for(int i=cnt-1;i>=0;i--)printf("%d ",count[i]);
            printf("%d
    ",len);
        }
        return 0;
    } 
    View Code
  • 相关阅读:
    实验证明:ObjectiveC++ 完美支持 ARC
    用 Java 实现的日志切割清理工具
    数字电视,方便了谁
    商品EAN13条码的生成
    关于错误“Cannot connect to the Citrix MetaFrame server.Can't assign requested address”的解决方法
    "加载类型库/dll时出错" 的解决方法
    解决连接SQL Server 2000的TCP/IP错误的Bug
    电脑自动关机之CPU风扇烧坏
    winrar 8 注册方法
    电脑死机之CPU温度过高
  • 原文地址:https://www.cnblogs.com/Mingusu/p/11793775.html
Copyright © 2011-2022 走看看