zoukankan      html  css  js  c++  java
  • POJ

    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

    题意:输入一个串,找到该串中所有前缀和后缀相等的长度,如例1中
    ab———————–ab
    abab—————-abab
    ababcabab-ababcabab
    ababcababababcabab-ababcababababcabab
    其中串长度本身必为一种解
    此处可根据next数组得出结果
    next数组所存储的是最长前缀后缀相等的长度。因此在原串中,除去串长这种解,第二个解就是next[len]的值。
    原串的前缀后缀求出后,前缀后缀的前缀后缀相等长度又在next数组中有体现,只需按照next数组中给定的next【i】值回溯,即可从长到短的顺序找到所有前缀后缀相等长度。递归输出即可。

    这里写图片描述
    主传的前缀和后缀的前缀和后缀相等
    主串的前缀和后缀相等
    主串

    假设黑色线来代表字符串str,其长度是len,红色线的长度代表next[len],
    根据next数组定义易得前缀的next[len]长度的子串和后缀next[len]长度的子串完全相同(也就是两条线所对应的位置)。
    我们再求出next[len]位置处的next值,也就是图中黄线对应的长度。
    同样可以得到两个黄线对应的子串肯定完全相同,又由于第二段黄线属于左侧红线的后缀,
    所以又能得到它肯定也是整个字符串的后缀。
    所以对于这道题,求出len处的next值,并递归的向下求出所有的next值,得到的就是答案。

    #include<stdio.h>///要找前缀后缀相同的,即利用KMP中NEXT数组里子串的重复性质来实现
    #include<string.h>///NEXT数组中,最后一位字符的next值表示从头到中间某一位,和中间某一位到末尾字符串相等
    char S[400005];///这就是模式串中前缀和后缀的最长相等位置,然后在前缀和后缀中继续找next值,即前缀和后缀的相等的前缀和后缀,这样递归下去可以得到所有的前缀和后缀的前缀和后缀的相等串
    int next[400005];
    void kmp_pre(char x[],int m)
    {
        int i,j;
        j=next[0]=-1;
        i=0;
        while(i<m)
        {
            while(j!=-1&&x[i]!=x[j])j=next[j];
            next[++i]=++j;
        }
    }
    void print_back(int x)
    {
        if(next[x]==0)return;
        print_back(next[x]);
        printf("%d ",next[x]);
    }
    int main()
    {
        while(scanf("%s",S)!=EOF)
        {
            int len=strlen(S);
            if(len==1)
            {
                printf("1
    ");
                continue;
            }
            kmp_pre(S,len);
            print_back(len);///注意next数组中每一位表示此之前一位是否和前缀相等,也就说如果是len-1位的next值其实表示的是len-2位字符是否和前缀中的字符相等
            printf("%d
    ",len);///因此要使后缀(最末尾位的字符)和前缀相等,应该使用next中len位置的的值,表示跳到
        }
    }
  • 相关阅读:
    C 库函数 ------ qsort()
    递归之美
    C函数库 ------ ctype.h
    scanf 多行输入判断结束
    POSIX库、glibc库、pthreads库、libc库、newlib、uClibc
    Docker 私有仓库搭建
    在daemon.json中配置主机后无法启动docker
    MySQL配置HeartBeat实现心跳监控和浮动IP
    Heartbeat基础知识-运维小结
    (二) Docker中启动镜像
  • 原文地址:https://www.cnblogs.com/kuronekonano/p/11135861.html
Copyright © 2011-2022 走看看