美文网首页
KMP算法swift版本

KMP算法swift版本

作者: 今年27 | 来源:发表于2022-07-21 15:43 被阅读0次
func KMP(_ str:String, _ pattenStr: String) -> Int {
    var j = 0
    let nexts = get_nexts(pattenStr)
    let strChars = Array(str)
    let pattenStrChars = Array(pattenStr)
    for i in 0..<str.count {
        while j > 0 && strChars[i] != pattenStrChars[j] {//遇到坏字符,查询nexts数组并改变模式串的起点
            j = nexts[j]
        }
        if strChars[i] == pattenStrChars[j] {
            j += 1
        }
        if j == pattenStr.count {
            return i - pattenStr.count + 1
        }
    }
    return -1
}

func get_nexts(_ pattenStr:String) -> [Int] {
    var nexts:[Int] = [Int](repeating: 0, count: pattenStr.count)
    let pattenChars = Array(pattenStr)
    var j = 0
    for i in 2..<pattenStr.count {
        while j != 0 && pattenChars[j] != pattenChars[i - 1] {//如果当前i-1于j无法匹配则 j = nexts[j]
            j = nexts[j];
        }
        if (pattenChars[j] == pattenChars[i - 1]) {//模板字符串最长可匹配的前缀字符串
            j += 1
        }
        nexts[i] = j//填充next[i]
    }
    return nexts
}

let str = "abcdabg"
let p = "cda"

let position = KMP(str, p)
print("position:\(position)")

nexts分析图

从上图中我们可以分析到,与其说是next数组,不如说是最小公共子前缀数组
那么问题来了,怎么求这个next数组呢?
根据我们前面分析的next数组的定义,可以找到下面的规律:
如果新加入的字符与前一个最长公共前缀子串的后一个字符相同:

next[i]与next[i-1]的关系
这里的深绿色部分长度是可以为0的,对后面计算没有影响。
next[i-1]与next[i]
在这种情况下,原来的深绿色部分就不能用了,显然,我们要缩小深绿色的部分,还要满足最长公共前缀子串的要求,也就像下面这个样子:
j = next[i]

这个蓝色的部分怎么求呢?这就是很多博客和代码里面没有说清楚的,最让人头痛的回退操作,就是那个臭名昭著的”j= next[j]“。
我们换一种理解方式,这个蓝色的部分,首先要内容相同,其次还要位于深绿色部分的开头和结尾,这不就是深绿色部分的最长公共前缀子串吗?


j=next[i]

也就是这样


j=next[i]

更新j = next[j]后,又回到这个问题的起点了,然后再次判断s[i-1]和s[j]是否相同就可以了。
至此,我们终于搞懂那个让人费解的回退操作到底是什么意思了,其实就是在当前的公共前缀已经不能用了,那就继续去尝试这个公共前缀的公共前缀,一直试到成功或者公共前缀的长度为0时为止。

参考文章
https://blog.csdn.net/Leycaner/article/details/108301195

相关文章

  • KMP算法swift版本

    从上图中我们可以分析到,与其说是next数组,不如说是最小公共子前缀数组那么问题来了,怎么求这个next数组呢?根...

  • Swift 实现KMP算法

    使用swift语言实现了一下KMP算法,具体代码如下 详细的描述了KMP算法推导next数组的流程 改进后的nex...

  • KMP 专题整理

    KMP 学习记录 kuangbin专题十六——KMP KMP 学习总结 朴素 KMP 算法 拓展 KMP 算法(E...

  • 对KMP算法的一些理解

    最近学到KMP算法,下面讲讲对KMP算法的一些个人理解,希望对大家有帮助! 对于KMP算法的理解: 整个KMP算法...

  • KMP算法文章合集

    字符串的查找:朴素查找算法和KMP算法 暴力匹配算法与KMP算法(串的匹配) 字符串查找算法BF和KMP 字符串匹...

  • 串的模式匹配算法

    KMP算法 算法匹配

  • 问答|KMP算法学习笔记

    问题 目录KMP是什么,做什么用的KMP算法的高效体现在哪如何KMP算法的next数组KMP的代码KMP的时间复杂...

  • KMP算法——寻找子串位置

    KMP算法——寻找子串位置 1、KMP算法简介: KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J....

  • 字符串匹配 - KMP算法

    前面我们介绍非常高效的 BM 算法,今天我们介绍另一个非常出名且高效的 KMP 算法。 KMP 算法思想 KMP ...

  • KMP算法及优化

    转载请注明出处: KMP算法及优化 今天看到同学在复习数据结构书上的KMP算法,忽然发觉自己又把KMP算法忘掉了,...

网友评论

      本文标题:KMP算法swift版本

      本文链接:https://www.haomeiwen.com/subject/bdguirtx.html