KMP算法C++实现

原创作者:Daniel

日期:2017.9.27

地点:大连理工大学软件学院

KMP算法包括两个过程:

1.计算模式的特征向量

int * next(string P ){
    int m = P.length();

    int* M = new int[m];

    M[0] = 0;

    for(int i = 1; i < m; ++i){

        int k = M[i -1];

        while(k > 0 && P[k] != P[i])
            k = M[k - 1];
        if(P[k] == P[i])
            M[i] = k + 1;
        else
            M[i] = 0;
    }

    return M;
}


2.KMP模式匹配算法

int KMPstring_match(const string & P, const string & T, int* next ){
    int i = 0;
    int j = 0;
    while(T[i] != '\0' && P[j] != '\0'){

        if(T[i ] == P[j]){
            i++;
            j++;
        }
        else{
            if(j == 0)
                i ++;
            else
                j = next[j - 1];
        }
    }

    if( j == P.length())
        return i - j;
    else
        return -1;
}



具体讲讲模式的特征向量的求法。

KMP算法实际上是根据模式自身的特点来简化传统模式匹配过程的,在传统配

过程中,每次匹配不满足时,都会将模式指针 p = 0,然后让目标上的指针 t ++,所

以,每匹配一次都会进行回溯,造成了效率低下,具体时间复杂度是:O(M*N);

下边是传统模式匹配C++代码:

int naive_string_match(string P, string T){
     int p = 0;
     int t = 0;
     int plen = P.length();
     int then = T.length();
     while(P[p] != '\0'&& T[t] != '\0'){

            if(P[p] == T[t]){
                 p++;
                 t++;
            }
           else{
               p = 0;
               t = t - p + 1  //为了将t移动到下一个匹配位置。
                }
   }
     if(p >= plen)
          return t - p;
     else
          return -1
}


可以看到,在匹配失败后,仅仅将模式右移动了一位。

特征向量 next()函数求法:

   特征向量的分量n[i]如下定义:

   1、n[0] = 0,对于 i > 0 的 n[I] ,n[i - 1] = k;

   2、如果i > 0,并且 P[k] = P[i],n[i] = k + 1;

   3、如果P[k] != P[i] , 令 k = n[k -1];

   4、如果P[k] != P[i] && k == 0 , n[i] = 0;

在 i 位置匹配失败后,就直接从P[i - n[i - 1]]继续匹配,避免了回溯。

在模式走到结尾时 返回 EOF;

模式匹配成功返回 i - j;


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值