码迷,mamicode.com
首页 > 编程语言 > 详细

KMP算法 初见

时间:2015-04-24 21:00:15      阅读:170      评论:0      收藏:0      [点我收藏+]

标签:

KMP算法

 

poj3461 Oulipo

题目大意:模板题。

思路:模板题。

技术分享
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int f[10010],ans;
char s1[10000],s2[1000000];
void prework()
{
    int i,j,n;
    n=strlen(s1);
    f[0]=f[1]=0;
    for (i=1;i<n;++i)
    {
        j=f[i];
        while(j&&s1[i]!=s1[j]) j=f[j];
        f[i+1]=(s1[j]==s1[i]?j+1:0);
    }
}
void work()
{
    int n,m,i,j;
    n=strlen(s1);m=strlen(s2);
    j=0;
    for (i=0;i<m;++i)
    {
        while(j&&s1[j]!=s2[i]) j=f[j];
        if (s1[j]==s2[i]) ++j;
        if (j==n) ++ans;
    }
}
int main()
{
    int i,n;
    scanf("%d",&n);
    for (i=1;i<=n;++i)
    {
        scanf("%*c%s%*c%s",&s1,&s2);
        prework();
        ans=0;work();
        printf("%d\n",ans);
    }
}
View Code

 

poj2752 Seek the Name, Seek the Fame

题目大意:求一个串前缀和后缀完全一样的所有长度。

思路:维护出f数组后,从最后一位循环一下,如果ch[j]==ch[f[j]],f[j]+1就是一个可行的长度,j=f[j],一直循环下去。突然发现f数组很神奇。其实我们能保证前f[j]+1个元素和以j为结尾的f[j]+1个元素一定是相等的。

技术分享
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char ch[400000];
int f[400001]={0},ans[400001]={0},l;
void prework()
{
    int i,j;
    f[0]=f[1]=0;
    for (i=1;i<l;++i)
    {
        j=f[i];
        while(j&&ch[i]!=ch[j]) j=f[j];
        f[i+1]=(ch[i]==ch[j]?j+1:0);
    }
}
void work()
{
    int j;
    j=l-1;
    while(j&&ch[j]==ch[f[j]])
    {
        ans[++ans[0]]=f[j]+1;
        j=f[j];
    }
}
int main()
{
    int i,j,n;
    while(scanf("%s",&ch)==1)
    {
        ans[0]=0;l=strlen(ch);
        ans[++ans[0]]=l;
        prework();
        work();
        for (i=ans[0];i;--i)
          printf("%d ",ans[i]);
        printf("\n");
    }
}
View Code

 

poj2406 Power Strings

题目大意:子串重复出现次数最多且重复后恰好是原串的长度。

思路:如果能重复后恰是原串的长度,那么l%(l-f[l])==0,如果能==0,则答案就是l/(l-f[l]),否则答案为1。这里一定是l和f[l],否则会出很多奇怪的问题。。。

技术分享
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char ch[1000000];
int f[1000001]={0},l;
void prework()
{
    int i,j;
    f[0]=f[1]=0;
    for (i=1;i<l;++i)
    {
        j=f[i];
        while(j&&ch[i]!=ch[j]) j=f[j];
        f[i+1]=(ch[i]==ch[j]?j+1:0);
    }
}
int main()
{
    int i,j,ans;
    while(scanf("%s",&ch)==1)
    {
        l=strlen(ch);
        if (ch[0]==.) break;
        prework();
        if (l%(l-f[l])==0) ans=l/(l-f[l]);
        else ans=1;
        printf("%d\n",ans);
    }
}
View Code

 

KMP算法 初见

标签:

原文地址:http://www.cnblogs.com/Rivendell/p/4454339.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!