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

1、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;
    }
}

2、KMP模式匹配算法的改进与优化数组

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

      如图所示,咱们能够看到,字串 T 在第5个位置就失配了:code

      

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

      

      咱们就会发现尽管这是按照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;
    }
}

 

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

相关文章
相关标签/搜索