首页 > 其他分享 >KMP

KMP

时间:2023-03-15 22:15:15浏览次数:46  
标签:匹配 开始 len next KMP match

KMP

算法思路

有如下情况(这里原串&子串都是从1开始)

原串\(s\)(以下简称\(s\))和子串\(p\)(以下简称\(p\))进行匹配,直到黑色分界线时都是匹配的,直到其后面一个元素不相等,\(s[i] \ne p[j + 1]\)

屏幕截图 2023-03-15 211305

首先在这样的情况下,我们可以通过移动\(p\)来实现\(s[i] = p[j + 1]\);如果直接回溯\(s\)的话,效率过低。

图如下:

屏幕截图 2023-03-15 212432

那么这样就可以运用到之前已经匹配了的\(s\),这里不难看出,这个\(p\)移动的距离就是\(next[j]\);而通过观察发现这个\(next[j]\)就是寻找到一个与以j为后缀的串相等的最长的前缀串(不包含其自身);所以那么\(s\)与\(p\)匹配的过程中若不匹配了,那么\(p\)就回退到\(next[j]\),然后再进行比较,直到退无可退或者是已经匹配了。当\(j = len(p)\)时,就表示匹配成功,同时将\(j = next[j]\)(因为匹配成功后,之后的情况就是不匹配了,与之前的情况类似,所以也需要回退一下)

match code

//  返回匹配成功后,开始进行匹配的位置
//	因为在匹配演示的过程中是j + 1 和 i进行比较的,故s从1开始,p从0开始
func match(s, p []byte) (res []int) {
    n := len(s)
    for i, j := 1, 0; i <= n; i++ {
        for j != 0 && s[i] != p[j + 1] {
            j = next[j]
        }
        if s[i] == p[j + 1] {
            j++
        }
        if j == n {
            res = append(res, j - n + 1)
            j = next[j]
        }
    } 
    return
}

当然还需要预处理出\(next\)数组,仔细分析以下,其实match的过程是类似的。当\(p[i] != p[j + 1]\),那么也就开始移动\(p\)串,直到其为相等或者是到了退无可退的情况;

pre-treatment code

// 从2开始是因为next[1]是退无可退的情况,故next[1] = 1;所以从2开始即可
func preTreatment(p []byte) (next []int) {
    m := len(p)
    for i, j := 2, 0; i <= m; i++ {
        for j != 0 && p[i] != p[j + 1] {
            j = next[j]
        }
        if p[i] == p[j + 1] {
            j++
        }
        next[j] = j
    }
    return
}

参考资料

标签:匹配,开始,len,next,KMP,match
From: https://www.cnblogs.com/hellozmc/p/17220321.html

相关文章

  • 字符串匹配之KMP算法中的pnext表
    pnext表的分析上篇我们提到了最后是构建一个pnext表,记录着每个字符匹配需要移动的长度的位置信息,接着上篇的内容,我们来分析下pnext表的构造。还是举个栗子:ababcabcacb......
  • 算法训练Day9| LeetCode28. 找出字符串中第一个匹配项的下标(KMP算法)
    28. 找出字符串中第一个匹配项的下标给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从0开始)。如果......
  • KMP算法
    KMP算法是字符串匹配算法,就是从指定字符串里找到匹配串匹配的位置字符串匹配无非是一个个去匹配单个字符,按照通常的思路,我们只需要从头开始一个个往下比就是,但是这样的效......
  • KMP字符串匹配算法——PMT数组的计算
    Leetcode28.找出字符串中第一个匹配项的下标KMP算法和PMT的介绍如何更好地理解和掌握KMP算法?-海纳的回答-知乎KMP算法PMT数组与next数组构造解释KMP算法就是......
  • kmp 与最小循环节
    题目:一个字符串的前缀是从第一个字符开始的连续若干个字符,例如abaab共有5个前缀,分别是a,ab,aba,abaa,abaab。我们希望知道一个N位字符串S的前缀是否具有循环节。......
  • KMP算法(字符串匹配算法最优解)
    KMP算法重点在于求next数组,理解next数组的含义。next数组的作用是当某次子串和主串匹配失败时,迅速的判断出字串索引j应该等于多少,而不回退主串的索引i,从而减少时间复杂度,......
  • kmp与循环节的关系
    对于一个字符串,长度是1~n(需要从1开始,而不是0),它的最小循环节T等于该字符串的长度减去它对应的next[n]数组,数组的小标是中这个字符串的结尾,该字符串的循环节长度一......
  • KMP的相关定义与性质
    声明:本文整理了北大附中肖然老师关于KMP讲解的核心要点。符号子串:从原串中选取连续的一段,即为子串;空串也是子串前缀:pre(s,k)为s前k个字符构成的子串后缀:suf(s,......
  • 学习笔记 // KMP
    智力问我,为什么要学KMP呢?时间复杂度甚至不如字符串哈希!我说,智力,你要不猜猜为什么这个世界上有扩展KMP,但是没有扩展字符串哈希?考虑暴力匹配字符串串,我们以长串串中的......
  • 「AcWing学习记录」KMP
    AcWing831.KMP字符串原题链接1.暴力算法怎么做chars[N],p[M];for(inti=1;i+m-1<=n;i++){boolflag=true;for(intj=1;j<=m;j++)......