朴素的字符串查找的复杂度是 O(MN) 的,显然这里有很大的优化空间,KMP 算法 (Knuth-Morris-Pratt) 可优化至 O(M+N)。
引入 next[]
注:本文使用 Python 的 slice,即 [b:e] 为左闭右开
假设比较如下字符串(上行为 S,下行为 W)
当发现 ‘D’ 与 ‘X’ 不符时,并不需要重新比较 ‘BCABX……’ 和 ‘ABCABD……’ ,而是根据 W 本身的性质,紧接着比较 ‘X……’ 和 ‘CABD……’
可视为在匹配 S 的 ‘X’ 时,比较的字符从 ‘D’(W[5]) “跳至” ‘C’(W[2])
之所以可以这样比较,是因 为 W[0:2] == W[3:5] == ‘AB’
对于 W 中的所有字符,都有这样的允许“跳至”的位置,不妨记录至 next[]数组,例如对于上例的 W,next[5] = 2
参考上文,对于 W,我们这样定义 next[] 数组
1 | next[i] = max{j | W[0:j] == W[i-j:i] for -1 <= j < i} |