zoukankan      html  css  js  c++  java
  • 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
    ",i,i/tmp);
        }
    }
    
    int main(){
        int n,m=0;
    
        while(~scanf("%d",&n)&&n){
            scanf("%s",str);
            GetNext(str);
            printf("Test case #%d
    ",++m);
            KMPCount2(str);
            printf("
    ");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Finding Palindromes POJ
    吉哥系列故事——完美队形II HDU
    Period II FZU
    生日礼物&&Supermarket
    炮兵阵地[状态压缩DP]
    最小表示法 P1368
    Period
    最长异或路径
    Luogu P5490 扫描线
    解方程
  • 原文地址:https://www.cnblogs.com/gongpixin/p/4729483.html
Copyright © 2011-2022 走看看