hdu 1358 Period(kmp求一个串的重复子串)

题意:统计单串中从某个位置以前有多少重复的串

思路:kmp模板

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;

#define MaxSize 1000005

char str[MaxSize];
int next2[MaxSize];

void GetNext(char t[]){
    int j,k,len;
    j=0;
    k=-1;
    next2[0]=-1;
    len=strlen(t);
    while(j<len){
        if(k==-1||t[j]==t[k]){
            ++j;
            ++k;
            next2[j]=k;
            /*优化
            if(t[j]!=t[k])next[j]=k;
            else next[j]=next[k];
            */
        }
        else k=next2[k];
    }
}

int KMPIndex(char s[],char t[]){
    int i,j,lens,lent;
    i=j=0;
    lens=strlen(s);
    lent=strlen(t);

    while(i<lens&&j<lent){
        if(j==-1||s[i]==t[j]){
            ++i;
            ++j;
        }
        else j=next2[j];
    }
    if(j>=lent)return i-lent;
    else return -1;
}

int KMPCount(char s[],char t[]){//统计子串在主串中的出现次数,可重叠
    int i,j,lens,lent,cnt;
    i=j=0;
    lens=strlen(s);
    lent=strlen(t);
    cnt=0;

    while(i<lens){
        if(j==-1||s[i]==t[j]){
            ++i;
            ++j;
        }
        else j=next2[j];
        if(j==lent)++cnt;
    }
    return cnt;
}

void KMPCount2(char t[]){//统计单串中从某个位置以前有多少重复的串
    int i,lent,tmp;
    lent=strlen(t);

    for(i=2;i<=lent;++i){
        tmp=i-next2[i];
        if(i%tmp==0&&i/tmp>1)
            printf("%d %d\n",i,i/tmp);
    }
}

int main(){
    int n,m=0;

    while(~scanf("%d",&n)&&n){
        scanf("%s",str);
        GetNext(str);
        printf("Test case #%d\n",++m);
        KMPCount2(str);
        printf("\n");
    }
    return 0;
}
View Code

 

posted @ 2015-08-14 11:26  gongpixin  阅读(395)  评论(0编辑  收藏  举报