HDU 2594 Simpsons’ Hidden Talents (KMP的F数组应用)

本文深入讲解了KMP算法中f数组的意义及计算方法,并通过示例代码展示了如何利用KMP算法寻找两个字符串间的最大公共前后缀长度。

KMP中f数组意义:对于模式串的前i个字母构成的子串,这个子串会有一些前缀和后缀完全相同(包括长度),f[i]表示的就是这个最大的长度,而长度确定了前缀后缀就确定了。

对于这个题,如果将s1,s2连接成一个串c,c的长度为lc,那么f[lc]就是题目中要求的最大长度。


注意如果f[lc]大于la或lb,那么要修改成la和lb中的最小值lmin,至于为什么一定存在长度为lmin的相同前后缀,这个自己画一下图就知道了,思想就是对于后缀中的一部分对应着前缀中的一部分,而这部分在后缀中又对应前缀中的一部分,这样传递下去。


代码:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

char a[50005];
char b[50005];
char c[100005];
int f[100005];
int main(){
    while(~scanf("%s%s",a,b)){
        int la=strlen(a);
        int lb=strlen(b);
        strcpy(c,a);
        strcat(c,b);
        int lc=strlen(c);
        f[0]=f[1]=0;
        for(int i=1;i<lc;i++){
            int j=f[i];
            while(j&&c[i]!=c[j]) j=f[j];
            f[i+1]=(c[i]==c[j]?j+1:0);
        }
        int res=f[lc];
        res=min(res,la);
        res=min(res,lb);
        if(res){
            for(int i=0;i<res;i++){
                printf("%c",c[i]);
            }
            printf(" %d\n",res);
        }
        else printf("%d\n",res);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值