KMP算法笔记

文本串:aabaabaaf 模式串:aabaaf
前缀:包含所有首字母,不包含尾字母的所有子串。
后缀:包含所有尾字母,不包含首字母的所有子串
最长相等前后缀:
a:0 ->不存在前后缀
aa:1 ->前缀a,后缀a
aab:0 ->前缀a,aa,后缀b,ab
aaba:1 ->前缀a,aa,aab,后缀a,ba,aba
aabaa:2 ->前缀a,aa,aab,aaba,后缀a,aa,baa,abaa
aabaaf:0 ->前缀a,aa,aab,aaba,aabaa,后缀f,af,aaf,baaf,abaaf

模式串的前缀表:010120
KMP算法笔记_第1张图片
i表示后缀末尾,j表示前缀末尾
以下是使用Java实现的KMP算法示例代码:

public class KMPAlgorithm {
    public static void main(String[] args) {
        String text = "ABABABCABAAABABABABCABAA";
        String pattern = "ABABABCABAA";
        int result = kmpSearch(text, pattern);
        System.out.println("匹配的起始位置为:" + result);
    }

    public static int[] getNext(String pattern) {
        int m = pattern.length();
        int[] next = new int[m];
        int i = 0, j = -1;
        next[0] = -1;
        while (i < m - 1) {
            if (j == -1 || pattern.charAt(i) == pattern.charAt(j)) {
                next[++i] = ++j;
            } else {
                j = next[j];
            }
        }
        return next;
    }

    public static int kmpSearch(String text, String pattern) {
        int n = text.length();
        int m = pattern.length();
        int i = 0, j = 0;
        int[] next = getNext(pattern);
        while (i < n && j < m) {
            if (j == -1 || text.charAt(i) == pattern.charAt(j)) {
                i++;
                j++;
            } else {
                j = next[j];
            }
        }
        if (j == m) {
            return i - j;
        } else {
            return -1;
        }
    }
}

这段Java代码实现了KMP算法的核心逻辑,包括计算next数组的getNext()函数和执行字符串匹配的kmpSearch()函数。通过运行这段代码,可以找到文本串中模式串的起始位置。
总结:KMP算法是一种高效的字符串匹配算法,通过计算next数组,我们可以在失配时跳过不必要的字符比较,从而大大提高搜索效率。

class Solution {
    /**
     * 基于窗口滑动的算法
     * 

* 时间复杂度:O(m*n) * 空间复杂度:O(1) * 注:n为haystack的长度,m为needle的长度 */ public int strStr(String haystack, String needle) { int m = needle.length(); // 当 needle 是空字符串时我们应当返回 0 if (m == 0) { return 0; } int n = haystack.length(); if (n < m) { return -1; } int i = 0; int j = 0; while (i < n - m + 1) { // 找到首字母相等 while (i < n && haystack.charAt(i) != needle.charAt(j)) { i++; } if (i == n) {// 没有首字母相等的 return -1; } // 遍历后续字符,判断是否相等 i++; j++; while (i < n && j < m && haystack.charAt(i) == needle.charAt(j)) { i++; j++; } if (j == m) {// 找到 return i - j; } else {// 未找到 i -= j - 1; j = 0; } } return -1; } }

你可能感兴趣的:(算法学习,算法,笔记,java)