KMP算法

参考视频:https://www.bilibili.com/video/BV1AY4y157yL/

KMP模式串指针回退:

next数组计算:

func KMP(str string, pattern string)int{
    m := len(str)
    n := len(pattern)
    if m == 0 || n == 0{
        return -1
    }
    // next[i]记录了以i结尾的pattern最长公共前后缀的长度
    next := nextGen(pattern)
    i, j := 0, 0
    for i < m{ // i永不回退
        if str[i] == pattern[j]{
            i++
            j++
        }else{
            if j == 0{ // pattern首字母就不匹配
                i++
            }else{ // j回退到pattern[0:j]最长公共前缀的位置
                j = next[j-1]
            }
        }
        if j == n{ // 匹配成功
            return i-n
        }
    }
    return -1

}
func nextGen(pattern string)[]int{
    // 返回以i结尾字符串最长公共前后缀的长度
    n := len(pattern)
    next := make([]int, n)
    if n == 0{
        return next
    }
    next[0] = 0
    prefixLen := 0
    for i := 1; i < n; {
        if pattern[prefixLen] == pattern[i]{ // 下一个字符依然相同
            prefixLen++
            next[i] = prefixLen
            i++
        }else{
            if prefixLen == 0{
                next[i] = 0
                i++
            }else{
                // prefixLen此时为next[i-1]的值,表示前一个位置最长公共前后缀长度
                // 相当于 prefixLen = next[next[i-1]-1],意味着已经有prefixLen个字母匹配
                // 下一个待匹配位置为index = prefixLen,因此再判断 pattern[prefixLen] == pattern[i]
                prefixLen = next[prefixLen-1]
            }
        }
    }
    return next
}

 

posted @   Saturn5  阅读(22)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示