#kmp
KMP算法威名赫赫,我学习的时候感觉非常惊叹。但是重复学习了n次,总是忘记。。。
最终我选择写这篇博客,一是为了记录自己的学习过程、思考过程,二是希望有想了解kmp的朋友有一点收获。
才疏学浅,如有纰漏,深感抱歉。)希望指正在评论区
KMP究竟解决一个什么样的问题?
在字符串中查找子串问题
这个问题就是给你一个长的字符串,还有一个短的字符串,请你查找长的字符串中有没有包含短的字符串,如果有,在哪个位置。
时间复杂度
其实本能我们会想到的就是暴力匹配,从长字符串的第一位开始,一个个的和短字符串匹配。显而易见,这个的时间复杂度是O(n3),而KMP算法就能将这个过程优化到O(n)
总结
KMP算法就是在线性时间复杂度下解决在字符串中查找子串问题
KMP算法究竟做了什么,核心是前缀函数
前缀函数是什么?
前缀函数就是一个数组,这个可以去百度百科一下。
有了这个前缀数组的概念,我们就很容易想到构造一个新的字符串
将短字符串和长字符串用一个特殊的字符连接,顺序不能乱,特殊字符需要不在短字符串中出现,也不能在长字符串中出现。
这样问题就化归到:什么时候前缀函数值等于短字符串的长度,这个位置就是子串的末尾,我们就找到了。
前缀函数怎么求呢?
暴力匹配 o(n3)
枚举前缀函数的自变量
枚举前缀函数的值
一一匹配校验
第一个优化的地方就是考虑到下一位的前缀函数值和当前前缀函数值的关联
值最多加1
这里的时间复杂度就是o(n2),计算用到了摊还分析,想了解我可以单独出一个博客。
第二个优化的地方就是匹配失败时,前缀函数值会减小到什么地方?
他会减小到(当前位置的前缀函数值)的前缀函数值,这个比较绕,可以思考一下,根据这些,就可以理解kmp的核心其实就是前缀函数。