面试算法--KMP字符串查询算法

题目:假设有一个主字符串S,以及一个子字符串P。请写出一个算法,解决在S中是否包含P,如果存在返回P在S中的位置,否则返回-1. 比如:主串为 “ABCDEFJIOH”,子串为“DEF”。 则返回结果为 3。

针对上面的题目,我们通常能想到的方法就是定义两个int变量i和j来分别指示S和P的下标。然后依次的遍历。

  • 如果当前字符匹配成功(即S[i] == P[j]),则i++,j++,继续匹配下一个字符
  • 如果失配(即S[i]! = P[j]),令i = i – (j – 1),j = 0。相当于每次匹配失败时,i 回溯,j 被置为0

具体的代码实现如下所示:

public static int getSubPos(String original, String desString){
        int oLength = original.length();
        int dLength = desString.length();

        int i = 0, j = 0;

        while(i < oLength && j < dLength){
            if(original.charAt(i) == desString.charAt(j)) {
                i++;
                j++;
            } else {
                i = i - j + 1;
                j = 0;
            }
        }
        if (j == dLength)
            return i - j;
        else
            return -1;
} 

而使用KMP算法则会大大降低时间复杂度,具体代码实现如下:

public static int KMP(String ts, String ps) {

    char[] t = ts.toCharArray();

    char[] p = ps.toCharArray();

    int i = 0; // 主串的位置

    int j = 0; // 模式串的位置

    int[] next = getNext(ps);

    while (i < t.length && j < p.length) {

       if (j == -1 || t[i] == p[j]) { // 当j为-1时,要移动的是i,当然j也要归0

           i++;

           j++;

       } else {

           // i不需要回溯了

           // i = i - j + 1;

           j = next[j]; // j回到指定位置

       }

    }

    if (j == p.length) {

       return i - j;

    } else {

       return -1;

    }

}

public static int[] getNext(String ps) {

    char[] p = ps.toCharArray();

    int[] next = new int[p.length];

    next[0] = -1;

    int j = 0;

    int k = -1;

    while (j < p.length - 1) {

       if (k == -1 || p[j] == p[k]) {

           if (p[++j] == p[++k]) { // 当两个字符相等时要跳过

              next[j] = next[k];

           } else {

              next[j] = k;

           }

       } else {

           k = next[k];

       }

    }

    return next;

}

使用KMP的时间复杂度为O(M + N)

对于KMP的具体解释可以参考如下链接:
http://www.cnblogs.com/yjiyjige/p/3263858.html
https://www.youtube.com/watch?v=GTJr8OvyEVQ
https://www.youtube.com/watch?v=KG44VoDtsAA

    原文作者:KMP算法
    原文地址: https://blog.csdn.net/zxm317122667/article/details/53572095
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞