zoukankan      html  css  js  c++  java
  • KMP + 求相等前后缀--- POJ Seek the Name, Seek the Fame

    Seek the Name, Seek the Fame 

    Problem's Link:  http://poj.org/problem?id=2752


     

    Mean: 

    给你一个字符串,求这个字符串中有多少前缀是和后缀相等的, 按递增顺序输出这些前缀的长度。

    analyse:

    KMP之next数组的运用。

    next[k]表示的是s[0....next[k]] 和s[k-next[k] .... k] 这段是相等的,即以k结尾的最长相等前后缀长度。

    next[k-1]表示的是与s[0....k]具有最长后缀,且与s[0...k]具有最长前缀的位置。也就是在k位置失配后需要移到next[k-1]的位置。

    这里特别说明一下,失配后移到next[k]还是next[k-1],取决于next数组的开始编号。如果从0开始编号,那就移到next[k-1];从1开始编号,就移到next[k]。

    Time complexity: O(N)

     

    Source code: 

    /*
    * this code is made by crazyacking
    * Verdict: Accepted
    * Submission Date: 2015-07-28-08.55
    * Time: 0MS
    * Memory: 137KB
    */
    #include <queue>
    #include <cstdio>
    #include <set>
    #include <string>
    #include <stack>
    #include <cmath>
    #include <climits>
    #include <map>
    #include <cstdlib>
    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <cstring>
    #define  LL long long
    #define  ULL unsigned long long
    using namespace std;
    const int MAXN=400010;
    int n;
    char s[MAXN];
    int Next[MAXN];
    int ans[MAXN];
    void getNext()
    {
         Next[0]=0;
         for(int i=1,k=0;i<n;++i)
         {
               while(s[i]!=s[k]&& k) k=Next[k-1];
               if(s[i]==s[k]) ++k;
               Next[i]=k;
         }
    }
    int main()
    {
         ios_base::sync_with_stdio(false);
         cin.tie(0);
         while(~scanf("%s",s))
         {
               n=strlen(s);
               getNext();
               int k=n-1;
               int cnt=0;
               while(Next[k])
               {
                     ans[cnt++]=Next[k];
                     k=Next[k-1];
               }
               ans[cnt++]=n;
               sort(ans,ans+cnt);
               for(int i=0;i<cnt;++i)
               {
                     printf(i==cnt-1?"%d ":"%d ",ans[i]);
               }
         }
         return 0;
    }
    /*

    */
  • 相关阅读:
    POJ 1681 Painter's Problem(高斯消元法)
    HDU 3530 Subsequence(单调队列)
    HDU 4302 Holedox Eating(优先队列或者线段树)
    POJ 2947 Widget Factory(高斯消元法,解模线性方程组)
    HDU 3635 Dragon Balls(并查集)
    HDU 4301 Divide Chocolate(找规律,DP)
    POJ 1753 Flip Game(高斯消元)
    POJ 3185 The Water Bowls(高斯消元)
    克琳:http://liyu.eu5.org
    WinDbg使用
  • 原文地址:https://www.cnblogs.com/crazyacking/p/4681838.html
Copyright © 2011-2022 走看看