kmp的作用
找到text中模式pattern的出现的pos
时间复杂度o(m + n)
Python实现
def kmp(self, text: str, pattern: str) -> List[int]:m = len(pattern)pi = [0] * mc = 0for i in range(1, m):v = pattern[i]while c and pattern[c] != v:c = pi[c - 1]if pattern[c] == v:c += 1pi[i] = cres = []c = 0for i, v in enumerate(text):v = text[i]while c and pattern[c] != v:c = pi[c - 1]if pattern[c] == v:c += 1if c == len(pattern):res.append(i - m + 1)c = pi[c - 1]return res
Go实现
func kmp(text, pattern string) (pos []int) {m := len(pattern)pi := make([]int, m) // 前后缀匹配的长度, 不包括自身cnt := 0 // dpfor i := 1; i < m; i++ {v := pattern[i]// 若最大匹配不匹配,找次大匹配for cnt > 0 && pattern[cnt] != v {cnt = pi[cnt - 1]}// 如果匹配了长度加一if pattern[cnt] == v {cnt++}pi[i] = cnt // pi[i]表示到第i个前后缀匹配的最大长度}cnt = 0for i, v := range text {// 遍历textfor cnt > 0 && pattern[cnt] != byte(v) {cnt = pi[cnt - 1]}if pattern[cnt] == byte(v) {cnt++}// 若匹配长度就是m,成功if cnt == m {pos = append(pos, i - m + 1)cnt = pi[cnt - 1] // 回退一个,为后面的做准备}}return
}