zoukankan      html  css  js  c++  java
  • [POJ]poj1961,poj2406(KMP)

    题意:求字符串的最小循环节长度,一个只要求原字符串的,一个要求所有前缀串的。

    考虑KMP算法中的next数组,next[i]+1表示使前缀后缀相等的最大长度,可以推知L=s.size()-next[i]-1为字符串的最小循环节长度。

    当s.size()是L的整数倍时,L即是循环节长度,否则最后一个循环节不完整(如abcabca),答案只能是s.size()。

    (问题:如何证明当x为最小循环节长度时,如果y不是x的倍数,循环节长度一定不能为y?)

    两题都可以一遍getnext实现。O(n)

    #include <iostream>
    #include <string>
    
    using namespace std;
    const int N =1E6+7;
    int nxt[N];
    
    void getnxt(string s){
        int k=-1;
        nxt[0]=-1;
        for(int i=1;i<s.size();i++){
            while(k!=-1&&s[i]!=s[k+1])k=nxt[k];
            if(s[i]==s[k+1])k++;
            nxt[i]=k;
            int re=i+1-nxt[i]-1;
            if((i+1)%re==0&&re!=i+1)cout<<i+1<<" "<<(i+1)/re<<endl;
        }
    }
    
    int main()
    {
       int x,cnt=0;
       string s;
       while(cin>>x){
            if(!x)break;
            cin>>s;
            cout<<"Test case #"<<++cnt<<endl;
            getnxt(s);
            cout<<endl;
       }
    }
    1961
    #include <iostream>
    #include <string>
    
    using namespace std;
    const int N =1E6+7;
    int nxt[N];
    
    void getnxt(string s){
        int k=-1;
        nxt[0]=-1;
        for(int i=1;i<s.size();i++){
            while(k!=-1&&s[i]!=s[k+1])k=nxt[k];
            if(s[i]==s[k+1])k++;
            nxt[i]=k;
        }
    }
    
    int main()
    {
       string s;
       while(cin>>s){
            if(s[0]=='.')break;
            getnxt(s);
            int re=s.size()-nxt[s.size()-1]-1;
            if(s.size()%re)cout<<1<<endl;
            else cout<<s.size()/re<<endl;
       }
    }
    2406
  • 相关阅读:
    【go语言学习】标准库之time
    【go语言学习】文件操作file
    【go语言学习】反射reflect
    【go语言学习】通道channel
    soap添加
    ubuntu apache 启用gzip
    git 版本回退
    ubuntu打开crontab日志及不执行常见原因
    Ionic3 怎么打开第三方 app,最简单粗暴的方法
    Windows安装使用Openssl创建pks p12证书
  • 原文地址:https://www.cnblogs.com/xutianshu/p/10185733.html
Copyright © 2011-2022 走看看