zoukankan      html  css  js  c++  java
  • kmp入门小结

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

    设t = next[i]; next[i] 表示的是 i之前最大的t满足 s[0...t-1]  =  s[i-t...i-1]

    比如 0123 4 0123 5 ,next[9] = 4.

    结论:len - next[len] 为最小覆盖子串。

    Poj3461 Oulipo

    题意:给出两个串,问第二个串在第一个串中出现的次数

    /* ***********************************************
         Author        : 一个西瓜
         Mail          : 879447570@qq.com
         Created Time  : 2015-04-07 16:24:21
        Problem       : Oulipo
    ************************************************ */
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    #include <string>
    #include <vector>
    #include <cmath>
    #include <queue>
    #include <map>
    #include <set>
    using namespace std; 
    #define INF 1000000000
    //typedef __int64 LL; 
    
    const int maxn = 11111;
    int next[maxn];
    char str[maxn];
    char str1[maxn*100];
    
    void get_next(char *s)
    {
        next[0] = -1;
        int j = 0 ;int k = -1;
        int len = strlen(s);
        while(j<len){
            if(k==-1||s[j]==s[k]){
                j++;k++;next[j] = k;
            }
            else k = next[k];
        }
    }
    
    
    int gao(char *s1,char *s2)
    {
        int ans = 0;
        int len1 = strlen(s1);int len2 =strlen(s2);
        int j = -1;int k = -1;
        while(j<len2){
            if(k==-1||s1[k]==s2[j]){
                j++;k++;
                //printf("%d %d
    ",j,k);
            }
            else k = next[k];
            if(k==len1){
                ans++;k = next[k];
            }
        }
        return ans;
    }
    
    int main()
    {
        int T;
        cin>>T;
        while(T--){
            cin>>str;
            cin>>str1;
            get_next(str);
            int k = gao(str,str1);
            cout<<k<<endl;
        }
        return 0;
    }
    View Code

    Poj1961 Period

    就用到上面那个结论了

    /* ***********************************************
         Author        : 一个西瓜
         Mail          : 879447570@qq.com
         Created Time  : 2015-04-07 17:50:15
        Problem       : Period
    ************************************************ */
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    #include <string>
    #include <vector>
    #include <cmath>
    #include <queue>
    #include <map>
    #include <set>
    using namespace std; 
    #define INF 1000000000
    //typedef __int64 LL; 
    
    const int maxn = 1111111;
    int next[maxn];
    char str[maxn];
    void get_next(char *s)
    {
        int len =strlen(s);
        int j = 0;int k = -1;
        next[0] = -1;
        while(j<len){
            if(k==-1||s[j]==s[k]){
                j++;k++; next[j] = k;
            }
            else k = next[k];
        }
    }
    
    int main()
    {
        int Icase = 0 ;
        int n;
        while(scanf("%d",&n)&&n){
            if(Icase) cout<<endl;
            printf("Test case #%d
    ",++Icase);
            scanf("%s",str);
            get_next(str);
            int len = strlen(str); 
            for(int i = 1;i<len;i++){
                int t = i+1;
                if(t%(t - next[t])==0&&(t/(t-next[t])!=1)){
                    printf("%d %d
    ",t,t/(t - next[t]));
                }
            }
        }
        return 0;
    }
    View Code

    Poj2752 Seek the Name, Seek the Fame

    给出一个串,问哪些既是前缀,又是后缀。

    next数组不就是,到当前串的第i个位置,既是这个子串的前缀又是后缀的最长前缀么。迭代下去求就行了。

    /* ***********************************************
         Author        : 一个西瓜
         Mail          : 879447570@qq.com
         Created Time  : 2015-04-07 17:28:12
        Problem       : Seek the Name, Seek the Fame
    ************************************************ */
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    #include <string>
    #include <vector>
    #include <cmath>
    #include <queue>
    #include <map>
    #include <set>
    using namespace std; 
    #define INF 1000000000
    //typedef __int64 LL; 
    
    const int maxn = 4*1e5 +10;
    int next[maxn];
    char str[maxn];
    
    void get_next(char *s)
    {
        next[0] = -1;
        int len =strlen(s);
        int j = 0 ;int k = -1;
        while(j<len){
            if(k==-1||s[j]==s[k]){
                j++;k++;next[j] =  k;
            }
            else k = next[k];
        }
    }
    vector<int> q;
    int main()
    {
        while(scanf("%s",str)!=EOF){
            get_next(str);
            q.clear();
            int k = strlen(str);
            q.push_back(k);
            k = next[k];
            while(k){
                q.push_back(k);
                k = next[k];
            }
            for(int i = q.size() - 1;i>=0;i--){
                printf("%d ",q[i]);
            }
            cout<<endl;
        }
        return 0;
    }
    View Code

    Poj2406 Power Strings

    和1961一样的。

    /* ***********************************************
         Author        : 一个西瓜
         Mail          : 879447570@qq.com
         Created Time  : 2015-04-07 17:50:40
        Problem       : Power Strings
    ************************************************ */
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    #include <string>
    #include <vector>
    #include <cmath>
    #include <queue>
    #include <map>
    #include <set>
    using namespace std; 
    #define INF 1000000000
    //typedef __int64 LL; 
    
    const int maxn = 1e6+10;
    char str[maxn];
    int next[maxn];
    
    void get_next(char *s)
    {
        int len =strlen(s);
        int j = 0 ;int k = -1;
        next[0] = -1;
        while(j<len){
            if(k==-1||s[j]==s[k]){
                j++;k++; next[j] = k;
            }
            else k = next[k];
        }
    }
    
    int main() {
        while(cin>>str){
            if(str[0]=='.') break;
            get_next(str);
            int len = strlen(str);
            if(len%(len-next[len])==0)
            cout<<len / (len - next[len])<<endl;
            else cout<<1<<endl;
        }
        return 0; 
    }
    View Code
  • 相关阅读:
    张高兴的 UWP 开发笔记:用 Thumb 控件仿制一个可拖动 Button
    oracle并非所有变量都已绑定
    win7出现无法连接到代理服务器的错误,不能上网的问题的解决
    用asp.net c# HttpWebRequest获取网页源代码
    退出系统时跳出frame框架
    使用MagicAJax的AjaxPanel时有时会弹出"Using the AjaxCallHelper write methods outside of an AjaxCall is not allowed."
    UI学习网站
    Oracle服务无法启动,报:Windows无法启动OracleOraDb10g_home1TNSListener服务,错误 1067:进程意外终止。
    视频怎么下载大电脑上
    css模板
  • 原文地址:https://www.cnblogs.com/yigexigua/p/4442651.html
Copyright © 2011-2022 走看看