KMP算法

KMP算法

思路

  • 数组next[i]:表示位置为i的后缀所能匹配的最长的前缀的长度。如:"ababa"中第4个位置的字符 'a' 所能匹配的最长前缀为 "aba",next = 3;"abcdab"中第5个字符 'b' 所能匹配的最长的前缀为 "ab",next为2。

实现

辅助数组

private static int[] generateNext(String str){
    int len = str.length();
    int[] next = new int[len];

    for(int i = 2; i < len; i++)
    {
        int head = next[i-1];
        while(head > 0 && str.charAt(head+1) != str.charAt(i))
            head = next[head]; // 若无法延续前一个位置向后匹配,则跳转到前一个字符所匹配的位置继续向后匹配

        if(str.charAt(head+1) == str.charAt(i)) //此时已找到前面字符的匹配长度,再检查当前字符与后一个字符是否相等
            head++;

        next[i] = head; // head 即为以i为结尾的匹配前缀的最长长度
    }
    return next;
}

计算匹配

public static boolean match(String str1, String str2){
    str1 = '$'+str1;
    str2 = '$'+str2;
    int[] next = generateNext(str2);
    int len1 = str1.length(), len2 = str2.length();
    int head = 0;
    for(int i = 1; i < len1; i++)
    {
        while(head > 0 && str2.charAt(head+1) != str1.charAt(i)) // 如果不匹配,则最长可以跳转到开始后的head字符处
            head = next[head];
        if(str2.charAt(head+1) == str1.charAt(i)) // 如果当前字符匹配,则向后匹配
            head++;
        if(head == len2-1) // 匹配成功,直接返回
            return true;
    }
    return false;
}
原文地址:https://www.cnblogs.com/truestoriesavici01/p/13662858.html