字符串搜索算法
 字符串搜索算法 
 KMP 算法
KMP 算法是一种用于在一个主文本字符串 $S$ 中查找一个模式字符串 $P$ 的子串的算法.
 KMP 算法的时间复杂度是 $O(\textrm{len}(S)+\textrm{len}(P))$.
 KMP 算法的核心是构建一个部分匹配表, 用于在匹配失败时, 快速移动模式字符串.
 KMP 算法的部分匹配表(kmp_table)是一个数组, 数组的第 $i$ 个元素表示 P[:i] 的前缀和后缀的最长公共元素的长度.例如 P=abcabd, 那么 kmp_table(P)=[0,0,0,1,2,0]. 因此匹配到 P[5] 时, 如果不匹配, 那么直接从 P[table[4]]→P[2] 的位置开始匹配, 因为 P[3:5] 和 P[0:2] 是相同的字符串.
- 为模式字符串 $P$ 生成部分匹配表- 初始化 table为长度为 $P$ 的长度的数组, 初始值为 0. 初始化 $i$ 和 $j$ 为 1 和 0. $i$ 表示当前位置, $j$ 表示前缀的末尾位置.
- 循环直到 $i$ 到达 $P$ 的长度
 
- 初始化 
- 在主文本字符串 $S$ 中查找模式字符串 $P$. $P$ 和 $S$ 的指针设为 0 位置.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
def kmp_table(pattern):
    table = [0] * len(pattern)
    i, j = 1, 0
    while i < len(pattern):
        if pattern[i] == pattern[j]:
            j += 1
            table[i] = j
            i += 1
        else:
            if j > 0:
                j = table[j - 1]
            else:
                table[i] = 0
                i += 1
    return table
def kmp_search(text, pattern):
    table = kmp_table(pattern)
    i, j = 0, 0  # S匹配的位置, P匹配的位置
    while i < len(text):
        if text[i] == pattern[j]:
            i += 1
            j += 1
            if j == len(pattern):
                return i - j
        else:
            if j > 0:
                j = table[j - 1]
            else:
                i += 1
    return -1
 本文由作者按照  CC BY 4.0  进行授权

