KMP 字符串匹配

KMP算法进行模式匹配
(1)构造一个prefix回退子串。
(2)needle串中,每次匹配的是needle[j+1]。因此,prefix[0] = -1,也就是当第0个元素不匹配时,j = -1,那么下一个i匹配的就是needle[-1+1],也就是0号元素。

(3)prefix[i] 表示,needle的[0,i]区间组成的前缀和与后缀和相等的最长长度时的前缀下标(最长长度-1)。为什么要最长长度减1,原因是prefix[i] 表示子串要回退的位置。前缀与后缀不可重合,因此最长长度必须小于i+1。

(4)prefix[i] 求prefix[i+1]相当于又在进行kmp,可见下图。


KMP 字符串匹配_第1张图片
image.png
int strStr(string haystack, string needle) {
    int n = needle.size();
    if(n == 0)
        return 0;
    vector prefix(n, 0);
    prefix[0] = -1;
    
    for (int i = 1,j = -1; i < n; i++){
               //我们要比较的是j+1位置(重要)
        while (j!=-1 &&needle[j+1] != needle[i]) j = prefix[j];
        //j表示回退位置。退出while时,要么无处可退(j == -1,j+1 == 0),要么needle[j+1] == needle[i] 。
        if (needle[j+1] == needle[i]) j++;
        prefix[i] = j;
    }

    for (int i = 0,j = -1 ; i < haystack.size(); i++){           
        while (j != -1 && haystack[i] != needle[j+1]) j = prefix[j];
        if (haystack[i] == needle[j+1]) j++;
        if (j == n-1)  return i - n + 1;
    }

    return -1;
}

参考:
[1] 闫学灿大神 https://www.acwing.com/
[2] KMP讲解视频,讲的很清楚
https://www.bilibili.com/video/BV1Px411z7Yo/?spm_id_from=333.788.videocard.0

你可能感兴趣的:(KMP 字符串匹配)