目 录:
前面讲过字符串匹配的其他几种算法:字符串匹配算法之 BF、RK、BM。
本文用来讲解 KMP 算法及其应用,KMP 算法时间复杂度为:O(N + M),空间复杂度为:O(M)。
1、问题描述
给定两个字符串 O 和 f,长度分别为 n 和 m,判断 f 是否在 O 中出现,如果出现则返回出现的位置。常规暴力方法是遍历 o 的每一个位置,然后从该位置开始和 f 进行匹配,但是这种方法的复杂度是 O(N x M)。KMP 算法通过一个 O(M) 的预处理(next 数组)可以加速匹配速度,使匹配的复杂度降为 O(N + M)。
2、next 数组
注意:next 数组是针对标准串而言的(上图中 f 是标准串、O 是母串)。
其实字符串匹配算法理解起来并不难,非常直观,结果就要求要匹配的字符在两个串中一一对应。但是为了提高暴力解法的效率,就必须提高字符串的匹配速度,其实就是解决每次匹配失败如何往前多移几位的问题,不要每次都是匹配失败,移动一位再重头开始。next 数组就是来做这件事情的,每次匹配失败,查找匹配串匹配失败位置处对应的 next 值,标准串向前移动 next 值那么多的长度,然后再继续和母串匹配。
那下面就讲一下 next 数组究竟是什么:
如上图所示:next 数组存放的是字符串 f 的 i 位置前面字符串的最长前缀和最长后缀的匹配长度【前缀不能扩到最后一个字符,后缀也不能扩到第一个字符】。
- A 段字符串是 f 在 i 位置的最长前缀子串;
- B 段字符串是 f 在 i 位置的最长后缀子串;
- A 段字符串和 B 段字符串相等。
分析:在字符串 O 中寻找 f,当匹配到位置 i 时两个字符串不相等,这时我们需要将字符串 f 向后移动。常规方法是每次向后移动 1 位,但是它没有考虑前 i - 1