1.2 KiB
1.2 KiB
KMP
KMP 主要用在 pattern 匹配上。
比如给出一个字符串 s 和一个 pattern ,请找出 pattern 第一次在 s 中出现的下标。
最长公共前后缀
前缀是指不包含最后一个字符的所有以第一个字符开头的连续子串;
后缀是指不包含第一个字符的所有以最后一个字符结尾的连续子串。
比如字符串 aaabcaaa 的最长公共前后缀是 aaa ,最长公共前后缀长度就是 3 。
前缀表
next[i]
表示 s[0...i]
这个子字符串的最长公共前后缀长度。
基本思路
i
代表 pattern 的前缀结尾,j
代表 s 的后缀结尾。
我们假设 pattern[0...j]
和 s[i-j...i]
一开始是相等的,但是当 j
和 i
都自增了 1 之后就不完全相等了,即末尾的 pattern[j]
和 s[i]
不相同。
但是 pattern[0...j]
有一段前缀 pattern[0...k]
和 s
的一段后缀 s[i-k...i]
相同。
那么我们可以从 pattern[k+1]
开始匹配。
这个时候我们需要让 j
回退到 k+1
。那么怎么做呢?
实际上 k+1 == next[j-1]
。
参考 s0028 详细代码实现与注释