POJ2752题解——KMP入门

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

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\n",len);
    }
    return 0;
} 

原文地址:https://www.cnblogs.com/Mingusu/p/11793775.html

时间: 2024-10-05 05:04:57

POJ2752题解——KMP入门的相关文章

题解报告:hdu 2087 剪花布条(KMP入门)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2087 Problem Description 一块花布条,里面有些图案,另有一块直接可用的小饰条,里面也有一些图案.对于给定的花布条和小饰条,计算一下能从花布条中尽可能剪出几块小饰条来呢? Input 输入中含有一些数据,分别是成对出现的花布条和小饰条,其布条都是用可见ASCII字符表示的,可见的ASCII字符有多少个,布条的花纹也有多少种花样.花纹条和小饰条不会超过1000个字符长.如果遇见#字符

HDU 4300 Clairewd‘s message 拓展KMP入门

HDU 4300 Clairewd's message 拓展KMP入门 题意 原题链接 这个题关键是要读懂题意,我做的时候就没有读懂,泪.题意是说给你的一个两个字符串,一个是26个字母密码表,依次对应替换的字母.然后给你一个字符串,这个字符串是不完整的(完整的应该是前半部分是加密的,后半部分是解密了的),然而,给你的字符串一定是加密的部分+一部分解密的部分(可以是全部,也可以是没有),让你求出最短的完整字符串,包括密文和明文: 解题思路 考虑给出的字符串S加密部分一定全部给出,所以给出的字符串的

KMP入门

从头到尾彻底理解KMP 作者:July 时间:最初写于2011年12月,2014年7月21日晚10点 全部删除重写成此文,随后的半个多月不断反复改进. 1. 引言 本KMP原文最初写于2年多前的2011年12月,因当时初次接触KMP,思路混乱导致写也写得非常混乱,如此,留言也是"骂声"一片.所以一直想找机会重新写下KMP,但苦于一直以来对KMP的理解始终不够,故才迟迟没有修改本文. 然近期因在北京开了个算法班,专门讲解数据结构.面试.算法,才再次仔细回顾了这个KMP,在综合了一些网友的

KMP入门 博客推荐+模板+入门习题

KMP入门 入门介绍 KMP入门博客推荐 next数组讲解 模板代码 //这个是对next进行的优化 void getnext() //做的第一步是获得next[]的值 { int i=0,k=-1; next[0]=-1; while(i<lenb) { if(k==-1 || str[i]==str[k]) { i++; k++; if(t[i]==t[k]) next[i]=next[k]; else next[i]=k; } else k=next[k]; } } //没有带优化的部分

KMP入门(匹配)

Description Given two sequences of numbers : a[1], a[2], ...... , a[N], and b[1], b[2], ...... , b[M] (1 <= M <= 10000, 1 <= N <= 1000000). Your task is to find a number K which make a[K] = b[1], a[K + 1] = b[2], ...... , a[K + M - 1] = b[M].

HDU2203(KMP入门题)

亲和串 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 10862    Accepted Submission(s): 4940 Problem Description 人随着岁数的增长是越大越聪明还是越大越笨,这是一个值得全世界科学家思考的问题,同样的问题Eddy也一直在思考,因为他在很小的时候就知道亲和串如何判断了,但是发现,现在长

kmp入门小结

void get_next(char *s) { int len = strlen(s); int j = 0; int k = -1; while (j < len){ if (k == -1 || s[j] == s[k]){ j++; k++; next[j] = k; } else k = next[k]; } } 设t = next[i]; next[i] 表示的是 i之前最大的t满足 s[0...t-1]  =  s[i-t...i-1] 比如 0123 4 0123 5 ,next

HDU1711(KMP入门题)

Number Sequence Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 17971    Accepted Submission(s): 7854 Problem Description Given two sequences of numbers : a[1], a[2], ...... , a[N], and b[1], b

hdu 1358 period KMP入门

Period 题意:一个长为N (2 <= N <= 1 000 000) 的字符串,问前缀串长度为k(k > 1)是否是一个周期串,即k = A...A;若是则按k从小到大的顺序输出k即周期数: Sample Input 3 aaa 12 aabaabaabaab 0 Sample Output Test case #1 2 2 3 3 Test case #2 2   2 6   2 9   3 12  4 题目其实是来自于LA的..挺好的一道题,用的是原版的kmp.. 写写对KMP