Seek the Name, Seek the Fame POJ - 2752(拓展kmp)

题意:

  就是求前缀和后缀相同的那个子串的长度  然后从小到大输出

解析:

  emm。。。网上都用kmp。。。但。。。我。。用拓展kmp做的  这就是拓展kmp板题嘛。。。

求出extend数组后  把extend[i] == len - i 的放到vector中 最后排序输出就好了

#include <iostream>
#include <cstdio>
#include <sstream>
#include <cstring>
#include <map>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#include <cmath>
#define rap(i, a, n) for(int i=a; i<=n; i++)
#define rep(i, a, n) for(int i=a; i<n; i++)
#define lap(i, a, n) for(int i=n; i>=a; i--)
#define lep(i, a, n) for(int i=n; i>a; i--)
#define MOD 2018
#define LL long long
#define ULL unsigned long long
#define Pair pair<int, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define _  ios_base::sync_with_stdio(0),cin.tie(0)
//freopen("1.txt", "r", stdin);
using namespace std;
const int maxn = 400010, INF = 0x7fffffff;

int next[maxn],ex[maxn]; //ex数组即为extend数组
//预处理计算next数组
void GETNEXT(char *str)
{
    int i=0,j,po,len=strlen(str);
    next[0]=len;//初始化next[0]
    while(str[i]==str[i+1]&&i+1<len)//计算next[1]
    i++;
    next[1]=i;
    po=1;//初始化po的位置
    for(i=2;i<len;i++)
    {
        if(next[i-po]+i<next[po]+po)//第一种情况,可以直接得到next[i]的值
        next[i]=next[i-po];
        else//第二种情况,要继续匹配才能得到next[i]的值
        {
            j=next[po]+po-i;
            if(j<0)j=0;//如果i>po+next[po],则要从头开始匹配
            while(i+j<len&&str[j]==str[j+i])//计算next[i]
            j++;
            next[i]=j;
            po=i;//更新po的位置
        }
    }
}
//计算extend数组
void EXKMP(char *s1,char *s2)
{
    int i=0,j,po,len=strlen(s1),l2=strlen(s2);
    GETNEXT(s2);//计算子串的next数组
    while(s1[i]==s2[i]&&i<l2&&i<len)//计算ex[0]
    i++;
    ex[0]=i;
    po=0;//初始化po的位置
    for(i=1;i<len;i++)
    {
        if(next[i-po]+i<ex[po]+po)//第一种情况,直接可以得到ex[i]的值
        ex[i]=next[i-po];
        else//第二种情况,要继续匹配才能得到ex[i]的值
        {
            j=ex[po]+po-i;
            if(j<0)j=0;//如果i>ex[po]+po则要从头开始匹配
            while(i+j<len&&j<l2&&s1[j+i]==s2[j])//计算ex[i]
            j++;
            ex[i]=j;
            po=i;//更新po的位置
        }
    }
}
char s1[maxn];

int main()
{
    while(~scanf("%s", s1))
    {
        vector<int> v;
        EXKMP(s1, s1);
        int len = strlen(s1);
        for(int i=0; i<len; i++)
            if(ex[i] == len-i)
                v.push_back(ex[i]);
        sort(v.begin(), v.end());
        for(int i=0; i<v.size(); i++)
        {
            if(i != 0) printf(" ");
            printf("%d", v[i]);
        }
        printf("\n");

    }


    return 0;
}

猜你喜欢

转载自www.cnblogs.com/WTSRUVF/p/9475163.html
今日推荐