[KMP]poj 2752:Seek the Name, Seek the Fame

大致题意:
    给出一个字符串str,求出str中存在多少子串,使得这些子串既是str的前缀,又是str的后缀。从小到大依次输出这些子串的长度。

 

大致思路:
    如左图,假设黑色线来代表字符串str,其长度是len,红色线的长度代表next[len],根据next数组定义易得前缀的next[len]长度的子串和后缀next[len]长度的子串完全相同(也就是两条线所对应的位置)。我们再求出next[len]位置处的next值,也就是图中蓝线对应的长度。同样可以得到两个蓝线对应的子串肯定完全相同,又由于第二段蓝线属于左侧红线的后缀,所以又能得到它肯定也是整个字符串的后缀。

    所以对于这道题,求出len处的next值,并递归的向下求出所有的next值,得到的就是答案。

 

#include<iostream>
#include<cstring>
#include<stack>
#include<cstdio>
using namespace std;
const int nMax=1000005;
char pat[nMax];
int lenp,next[nMax];

void get_next(){
    int i,j=-1;
    next[0]=-1;
    for(i=1;i<=lenp;i++){
        while(j>-1&&pat[j+1]!=pat[i])j=next[j];
        if(pat[j+1]==pat[i])j++;
        next[i]=j;
    }
}

stack<int>ans;
int main(){
    while(scanf("%s",pat)!=EOF){
        lenp=strlen(pat);
        get_next();
        int j=next[lenp-1];
        while(j!=-1){
            ans.push(j);
            j=next[j];
        }
        while(!ans.empty()){
            cout<<ans.top()+1<<" ";
            ans.pop();
        }cout<<lenp<<endl;
    }
    return 0;
}
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值