KMP 算法

  • 需求:字符串中的模式定位问题
    • 主串:“abcxabcdabxabcdabcdabcy”
    • 模式串:“abcdabcy”
// 解法一:暴力破解
// 时间复杂度:O(mn)

public static int bf(String ts, String ps) {
    char[] t = ts.toCharArray();
    char[] p = ps.toCharArray();

    int i = 0; // 主串
    int j = 0; // 模式串

    while(i < t.length && j < p.length) {
        if (t[i] == p[j]) {
            i++;
            j++;
        } else {
            i = i - j + 1;
            j = 0;
        }
    }

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


// 解法二:KMP 算法
// 时间复杂度:O(m+n)
// Text:  abcxabcdabxabcdabcdabcy
// Pattern: abcdabcy 

// KMP Prefix Array Logic
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]) {
            next[++j] = ++k;
        } else {
            k = next[k];
        }
    }
    return next;
}

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]) {
            i++;
            j++;
        } else {
            // i不需要回溯
            j = next[j]; // j回到指定位置
        }
    }

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

参考资料:

原文地址:https://www.cnblogs.com/linkworld/p/11881354.html