加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

kmp(最长前缀与后缀)

发布时间:2020-12-13 22:16:58 所属栏目:PHP教程 来源:网络整理
导读: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 periodi

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 A K,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
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 #%dn",++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 %dn",i,i / l); // i / l 求由多少个相同的个相同字符串组成
            }
        }
        printf("n");
    }

    return 0 ;
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读