KMP总结

【介绍】
KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt同时发现,因此人们称它为克努特——莫里斯——普拉特操作(简称KMP算法)。

【思想】
对于给定的两个串A,B,长度分别为N,M让你查找B串在A串中的位置。
对于这么一个问题,我们首先的想法就是O(MN)的暴力枚举,但是假设M和N都大于10^6,那么就有可能扛不住了,这时候KMP就派上了用场。

设p为目前枚举到A串的位置,q为目前枚举B串的位置。
假设A串为abacabbc,B串为acab。
KMP的核心思想就是对B串进行自身匹配,节省了之后在A串中查找的时间,定义prefix数组记录自身匹配到的位置,如下:
acab
0010
自身匹配结束后,就可以在A串中查找了。
abacabbc
acab
p=1 q=1

abacabbc
    acab
p=3 q=1

abacabbc
    acab
p=6 q=4
匹配成功

再举个特殊例子:
比如说A串是zzkorzzzkzzk,B串是zzkzzk
自身匹配就是:
zzkzzk
010123

特殊的地方就是这种情况:
zzkorzzzkzzk
         zzkzzk
当p=8,q=2时,因为Ap!=Bq+1所以将q=prefix[q]相当于将B串向后移了一位。
如下:
zzkorzzzkzzk
          zzkzzk
此时p=8,q=1

【核心代码】
B串自身匹配:

void Getprefix(const char *a)//自身匹配,构造prefix数组。 
{
    int k=0,len=strlen(a+1); prefix[0]=prefix[1]=0;
    for (int i=2; i<=len; i++)
    {
        while (k>0&&a[k+1]!=a[i]) k=prefix[k];
        if (a[k+1]==a[i]) k++;
        prefix[i]=k;
    }
}

在A串中查找B串的位置:

void KMP(const char *a,const char *b)//在A串中查找B串的位置 
{ 
    int k=0,Alen=strlen(a+1),Blen=strlen(b+1);
    for (int i=1; i<=Alen; i++)
    {
        while (k&&b[k+1]!=a[i]) k=prefix[k];
        if (b[k+1]==a[i]) k++;
        if (k==Blen) {printf("%d",i-Blen+1); return;}
    }
    printf("-1");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值