数据结构与算法之KMP算法的实现和优化

一、KMP模式匹配算法的实现

// 返回字串T在主串S第pos个字符之后的位置
// 若不存在,则返回0

int Index_KMP(String S, String T, int pos){

    int i = pos;
    int j = 1;
    int next[255];

    get_next(T, next);

    while(i <= S[0] && j <= T[0]){
        
        if(0 == j || S[i] == T[j]){
            i++;
            j++;
        }else{
            j = next[j];
        }
    }

    if(j > T[0]){
        return i - T[0];
    }else{
        return 0;
    }
}
 

二、KMP模式匹配算法的改进与优化

     有人发现上面的KMP算法,其实是由缺陷的。比如我们的主串 S = "aaaabcde",字串 T = "aaaaax",其中很容易得到next数组为012345。

      如图所示,我们可以看到,字串 T 在第5个位置就失配了:

      

      如果按照上述代码实现的KMP算法的话,在子串 T 在第5个位置失配时,T开始寻找它的next,即从4开始回溯匹配,直到0,开始位置,发现都不匹配,那么此时主串 S 和子串 T都往前移动一个位置,即主串 S 到了第6个元素的位置,子串 S 也从位置0到了位置1,如下图所示:

      

      我们就会发现尽管这是按照KMP算法的思路进行匹配的,但是效率仍然不高,因为子串 T 的前5个都是相同的,所以回溯匹配(4,3,2,1与5相等,如果匹配肯定也是失配的!)时就会导致效率低下,所以,我们有必要进行改进,我们可以判断失配位置对应next数组中值的对应的位置的值是否相等(即判断位置5和位置4是否相等),即只要在next数组的计算过程中,如果说它的下一个元素跟之前的前缀元素相等的话,它就需要直接回溯到它前缀元素的next的值那里去,即回溯到它前缀元素next下标所指向的索引!代码如下:

// 返回字串T在主串S第pos个字符之后的位置
// 若不存在,则返回0

int Index_KMP(String S, String T, int pos){

    int i = pos;
    int j = 1;
    int next[255];

    get_next(T, next);

    while(i <= S[0] && j <= T[0]){
        
        if(0 == j || S[i] == T[j]){
            i++;
            j++;

            // 改进优化代码-------
            if(T[i] != T[j]){
                next[i] = j;
            }else{
                next[i] = next[j];
            }
            // 改进优化代码-------

        }else{
            j = next[j];
        }
    }

    if(j > T[0]){
        return i - T[0];
    }else{
        return 0;
    }
}
 

 

本文为原创文章,如果对你有一点点的帮助,别忘了点赞哦!比心!如需转载,请注明出处,谢谢!

 

转载于:https://my.oschina.net/aibinxiao/blog/1921737

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值