KMP的应用:Python和Go实现

kmp的作用

找到text中模式pattern的出现的pos
时间复杂度o(m + n)

Python实现

    def kmp(self, text: str, pattern: str) -> List[int]:
        m = len(pattern)
        pi = [0] * m
        c = 0
        for i in range(1, m):
            v = pattern[i]
            while c and pattern[c] != v:
                c = pi[c - 1]
            if pattern[c] == v:
                c += 1
            pi[i] = c

        res = []
        c = 0
        for i, v in enumerate(text):
            v = text[i]
            while c and pattern[c] != v:
                c = pi[c - 1]
            if pattern[c] == v:
                c += 1
            if 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 
    // dp
    for 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 = 0
    for i, v := range text {
        // 遍历text
        for 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
}

你可能感兴趣的:(python,开发语言)