KMP算法

KMP算法

KMP算法是一种比较高级的串匹配算法,是由Knuth、Morris和Pratt同时设计的。KMP算法-维基
普通的串匹配算法思路是将S[i]的每一位与T[0]~T[j]进行比较,如果s[i]!=T[j],则比较s[i+1]与T[0]~T[j]比较。
例1
在第一次匹配过程中,S[0]~S[3]和T[0]~T[3]匹配成功,S[4]!=T[4]匹配失败,因此有了第二次。因为在第一次中有S[1]=T[1],而T[0]!=T[1],因此有T[0]!=S[1],所以第二次是不必要的,同样第三次也是不必要的,可以直接到第四次。此进阶一次,i不回溯,j回溯到0。
进阶二:因为第一次中已经比较了S{3}=T[3],而T[0]=T[3],也因此必有S[3]=T[0],因此第四次比较可以直接比较S[4]和T[1]比较。此时是当T中含有对称性时候,T[0]对称T[3]而T[3]对应S[3],即T[0]=s[3]。因此,j可以不回溯到0,而是回溯到1。

例2

S=ababaababcb  T=ababc

新建数组next[],用于存储T的每位字符之前包含的对称性长度。
当第一次匹配时,S[4]!=T[4],此时查看T[4]的next值:next[4]=2;(计算参后)因此j回溯到2。因为S[2]S[3]=T[2]T[3],T[0]T[1]=T[2]T[3],所以S[2]S[3]=T[0]T[1],j不用回溯到0,而next对应的值便表示这个意思。
而如何计算next值呢?
next表示该位字符串前最大的对称性
0位为-1
上图的next值为{-1,0,0,1,2}

计算next方法C++代码

void GetNext(char T[],int next[])
{
    int i,j,len;
    next[0]=-1;
    for(j=1;T[j]!='\0';j++)//一次求next值
    {
        for(len=j-1;len>=1;len--)//对称性的最大长度为j-1,遍历长度递减
        {
            for(i=0;i<len;i++)//一次比较T[0]~T[len-1]与T[j-len]~T[j-1]
                if(T[i]!=T[j-len+i])break;

            if(i==len)
            {
                next[j]=len;break;
            }
        }
        if(len<1)next[j]=0;
    }
}

KMP算法C++代码

int KMP(char S[],char T[])
{
    int i=0,j=0;
    int next[80];
    GetNext(T,next);
    while(S[i]!='\0' && T[j]!='\0')
    {
        if(s[i]==T[j])
        {
            i++;j++;
        }else{
            j=next[j];
            if(j==-1){i++;j++;}
        }
    }
    if(T[j]=='\0') return (i-strlen(T)+1);//返回匹配的开始位置
    else return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值