引子
\(\text{KMP}\) 算法本质是用失配指针来优化暴力配对。
而我们用最长 \(\text{border}\) 来当做失配指针的本质在于:两个成功匹配区间的交必定是模式串的 \(\text{border}\)。
假设我们有两个长度分别为 \(n,m\) 的串 \(s,t\)。我们现在要找出 \(t\) 在 \(s\) 中所有出现位置的左端点下标。
思想简易概述
从左往右扫,如果每次下一个字符无法配对,就通过跳失配对指针。
因为下一个出现位置和当前的交必定是一个 \(t\) 的 \(\text{border}\)。
求解 \(t\) 的 \(\text{border}\) 方法类似,只不过是 \(t\) 的自我匹配过程,利用的是之前已有的信息。
特别的,记 \(t[1,i]\) 的最长 \(\text{border}\) 为 \(nxt_i\)。
引理性质总结
引理 \(1\):如果一个 \(s\) 的 \(\text{border}\) \(k\) 的长度不小于 \(s\) 的一半,那么 \(s\) 有一个长为 \(|k|\) 的 \(\text{period}\)。
逆定理同样成立。
引理 \(2\):如果 \(p,q\) 都是周期,那么 \(gcd(p,q)\) 也是周期
引理 \(3\):可以把字符串分为 \(\log\) 段,每一段的 \(nxt_i\) 都是一个等差数列。