kmp(所有长度的前缀与后缀)

http://poj.org/problem?id=2752

Seek the Name, Seek the Fame

Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 27512   Accepted: 14244

Description

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

Source

POJ Monthly--2006.01.22,Zeyuan Zhu

题意:求字符串所有的相同前缀与后缀;

思路:我们知道next数组是求最长前缀与后缀,如果要求所有,我们就要向前递归next数组直到为0,即可找出所有长度的前缀与后缀

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <algorithm>
#include <iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include <stdio.h>
#include <string.h>
using namespace std;
char a[1000009];
int next[1000009];
int num[1000009];
void getnext(char *a , int len , int *next)
{
    next[0] = -1 ;
    int k = -1 , j = 0 ;
    while(j < len)
    {
        if(k == -1 || a[k] == a[j])
        {
            k++;
            j++;
           // if(a[k] != a[j])
                next[j] = k;//next数组不能优化
          //  else
            //    next[j] = next[k];*/
        }
        else
            k = next[k];
    }
}

int main()
{
    while(~scanf("%s" , a))
    {
        memset(next , 0 , sizeof(next));
        memset(num , 0 , sizeof(num));
        int len = strlen(a);
        getnext(a , len , next);
        int l = 0 ;
        num[l++] = len ;
        while(next[len] > 0)//向前递归next数组
        {
            num[l++] = next[len];
            len = next[len];
        }
        for(int i = l - 1 ; i > 0 ; i--)
        {
            printf("%d " , num[i]);
        }
        printf("%d\n" , num[0]);
    }

    return 0 ;
}

原文地址:https://www.cnblogs.com/nonames/p/11294338.html

时间: 2024-08-01 11:10:47

kmp(所有长度的前缀与后缀)的相关文章

kmp(最长前缀与后缀)

http://acm.hdu.edu.cn/showproblem.php?pid=1358 Period Problem Description For each prefix of a given string S with N characters (each character has an ASCII code between 97 and 126, inclusive), we want to know whether the prefix is a periodic string.

POJ 2752 (KMP 所有可能长度的前缀后缀) Seek the Name, Seek the Fame

题意: 求一个字符串的相同前缀后缀的所有可能的长度,这里该字符串其本身也算自己的前缀和后缀. 分析: 我们知道next数组的性质是,该字符之前的字符串的最大相同前缀后缀. 既然知道了最大的,即next[len]. 递归一次next[ next[len] ],就能求得更小的前缀. 不断的递归把所有所有可能的长度找出来,然后递归输出即可. 1 #include <cstdio> 2 #include <cstring> 3 4 const int maxn = 400000; 5 ch

POJ 2752+KMP+利用next数组性质求出所有相同的前缀和后缀

题目链接:点击进入 这个题目要求所有相同的前缀和后缀的长度.我们可以利用KMP算法中next数组的性质,在next[len]这个点不断的失配下去,这样就可以将所有相同的前后缀的长度求出来.还要注意这个中整个串的长度也可以看成是一个合法的解. 代码如下: #include<iostream> #include<cstdio> #include<cstring> using namespace std; const int maxn=400000+100; char str

139. 回文子串的最大长度(回文树/二分,前缀,后缀和,Hash)

题目链接 : https://www.acwing.com/problem/content/141/ #include <bits/stdc++.h> using namespace std; const int MAXN = 1000005 ; const int N = 26 ; struct Palindromic_Tree { //cnt最后count一下之后是那个节点代表的回文串出现的次数 int next[MAXN][N] ;//next指针,next指针和字典树类似,指向的串为当

POJ 2752 Seek the Name, Seek the Fame(求所有既是前缀又是后缀的子串长度)

题目链接:http://poj.org/problem?id=2752 题意:给你一个字符串,求出所有前缀后缀(既是前缀又是后缀的子串)的长度 思路:首先整个字符串肯定既是前缀又是后缀,为最大的前缀后缀. 假设next[len] = k,也即:s[1,k] = s[len-k+1,len]此时s[1,k]是前缀后缀. 处理完next[len]后跳转到next[k+1],用这种方法可以得到所有的前缀后缀. code: 1 #include <cstdio> 2 #include <cstr

字符串前缀,真前缀,后缀,真后缀,及前缀函数

举个例子,如字符串 ababc 首先,不考虑空字符,所有的前缀有a, ab, aba, abab, ababc,其中真前缀有a, ab, aba, abab 同理可以理解后缀,真前(后)缀就是指不包含自身的前(后)缀 前缀函数next[j]是指某个字符串的最长真后缀同时也是它的前缀的子串长度.不太理解可以看下面的例子 a -> 0 ab -> 0 aba -> 1 abab -> 2 ababc -> 0 前缀函数在字符串的匹配中用的较多,如KMP等.它主要是表明在一次匹配失

前缀积和后缀积

Description: 给出数列A1,A2,...,AN,并设 Bi = (A1 * A2 * A3 ... AN) / Ai mod (109 + 7) 现要求把所有的Bi 算出来 Input: 输入包含多组测试数据.对于每组数据,第1 行,1 个整数N(1 ≤N ≤100,000), 表示数列的长度.第2 行,N 个整数A1,A2,...,AN(1 ≤Ai≤109),表示给出的数列.输入以一个 0 表示结尾. Output: 对于每组数据,输出一行,N 个整数用空格分隔,表示算出的B1,B

自增、自减运算符的前缀和后缀

试卷中有这么一道题目: 1 2 int a = 4; (++a) += i; 求a的数值,正确答案是10. 如果你认为这道题重点只是考察运算符优先级,可能很容易得到正确的答案. 但是,考虑过为什么下面的代码无法编译么? 自己在笔试时,考虑到了关于表达式作为赋值运算符左值的问题,但是自己确实又对重载"++"操作符的实现机制和函数原型不很了解,就误认为"a++"和"++a"这两种写法都不能作为赋值运算符左值,从而以为这道题出错了,或者故意考察这一点,

c++前缀和后缀++

1,c++规定后缀形式的++操作符有一个int行的参数,被调用时,编译器自动加一个0作为参数给他 2,前缀返回一个reference,后缀返回一个const对象 /////////////////////////////////////////////////////////////////////////////// // // FileName : meffect_item5.h // Version : 0.10 // Author : Ryan Han // Date : 2013/11