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. That is, for each i (2 <= i <= N) we want to know the largest K > 1 (if there is one) such that the prefix of S with length i can be written as AK , that is A concatenated K times, for some string A. Of course, we also want to know the period K.

Input

The input file consists of several test cases. Each test case consists of two lines. The first one contains N (2 <= N <= 1 000 000) – the size of the string S. The second line contains the string S. The input file ends with a line, having the number zero on it.

Output

For each test case, output “Test case #” and the consecutive test case number on a single line; then, for each prefix with length i that has a period K > 1, output the prefix size i and the period K separated by a single space; the prefix sizes must be in increasing order. Print a blank line after each test case.

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

Recommend

JGShining

题意:一个字符串,问输出所有:长度为多少(小于等于总长),能够由最少2个相同的子字符串组成

注意:单纯是求最长前缀与后缀的题目,最好不要进行next数组优化(匹配题可以使用)

#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];

void getnext(char *a , int len , int *next)
{
    next[0] = -1 ;
    int k = -1 , j = 0;
    while(j < len)
    {
        if(k == -1 || a[j] == a[k])
        {
            k++;
            j++;
            next[j] = k ;
        }
        else
        {
            k = next[k];
        }
    }
}

int main()
{
    int n , ans = 0 ;
    while(~scanf("%d" , &n) && n)
    {
        int next[1000009];
        scanf("%s" , a );
        printf("Test case #%d\n" , ++ans);

        memset(next , 0 , sizeof(next));
        getnext(a , n, next);//求next数组
        for(int i = 2 ; i <= n ; i++)//遍历每个大于2的字符串
        {
            //i % i (i - next[i])表示该字符串都由若干个(大于1个)相同的字符串组成
            if(next[i] >= 1 && i % (i - next[i]) == 0)
            {
                int l = i - next[i] ;
                printf("%d %d\n" ,i , i / l); // i / l 求由多少个相同的个相同字符串组成
            }
        }
        printf("\n");
    }

    return 0 ;
}

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

时间: 2024-07-29 07:43:25

kmp(最长前缀与后缀)的相关文章

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 aske

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

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

Codeforces Round #545 (Div. 2)D(KMP,最长公共前后缀,贪心)

#include<bits/stdc++.h>using namespace std;const int N=1000007;char s1[N],s2[N];int len1,len2;int nex[N];int cnt1[7],cnt2[7];int main(){    scanf("%s %s",s1+1,s2+1);    len1=strlen(s1+1);    len2=strlen(s2+1);    for(int i=1;i<=len1;i++

HDOJ 题目4691 Front compression(后缀数组+RMQ最长前缀)

Front compression Time Limit: 5000/5000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Others) Total Submission(s): 1652    Accepted Submission(s): 604 Problem Description Front compression is a type of delta encoding compression algorithm w

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

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

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指针和字典树类似,指向的串为当

将前缀和后缀相同的文件移动到同一个目录的算法设计及C代码实现

一.需求描述 在Linux系统的某几个目录下有一些前缀和后缀相同的文件,编写程序将它们移动到同一个目录下. 例如,有三个源目录FileDir1.FileDir2和FileDir3,里面分别存放有文件File_1.txt.File_2.txt和File_3.txt.由于它们有相同的前缀(File_)和后缀(txt),所以要将这三个文件移动到同一个结果目录(假设为GatherDir)中. 二.算法设计 基于需求,可以采用如图1所示的程序流程: 图1 程序总体流程 三.特殊流程考虑 在编写程序的过程中

COGS 696. [IOI1996][USACO 2.3] 最长前缀

★   输入文件:prefix.in   输出文件:prefix.out   简单对比时间限制:1 s   内存限制:128 MB 描述 USACO 2.3.1 IOI96 在生物学中,一些生物的结构是用包含其要素的大写字母序列来表示的.生物学家对于把长的序列分解成较短的序列(即元素)很感兴趣. 如果一个集合 P 中的元素可以通过串联(元素可以重复使用,相当于 Pascal 中的 “+” 运算符)组成一个序列 S ,那么我们认为序列 S 可以分解为 P 中的元素.元素不一定要全部出现(如下例中B

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

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