返回
字符串匹配: KMP 算法的部分匹配表
前端
2024-01-31 01:00:09
与暴力匹配算法相比,KMP 算法在匹配字符串时具有显著优势。这得益于其对源字符串的遍历中省略了部分循环,从而在某些情况下带来了可观的性能提升。
KMP 算法的部分匹配表解法是其核心。它通过比较模式串的前缀和后缀(概念不再赘述)得到一个部分匹配表数组,从而优化循环。
部分匹配表的构造
设模式串为 P = p1p2...pn
,部分匹配表 F[i]
表示以模式串前 i
个字符为后缀的字串中,与自身匹配的最长前缀的长度。
部分匹配表的构造过程如下:
F[0] = 0
- 对于
i = 1
到n
a. 若pi = pi-F[i-1]
,则F[i] = F[i-1] + 1
b. 若pi != pi-F[i-1]
,则
i. 若F[i-1] != 0
,则i = F[i-1]
,重新执行步骤 a
ii. 若F[i-1] = 0
,则F[i] = 0
算法过程
给定源字符串 S
和模式串 P
,KMP 算法的匹配过程如下:
- 设
i = 0
和j = 0
- 若
j = n
,则说明匹配成功,退出循环 - 若
i = m
,则j = F[j]
,并回到步骤 2 - 若
Si = Pj
,则i = i + 1
和j = j + 1
,并回到步骤 2 - 若
Si != Pj
,则j = F[j]
,并回到步骤 2
举例
设源字符串 S = abcabdabcabc
,模式串 P = abcab
,则部分匹配表为:
F[0] = 0
F[1] = 0
F[2] = 1
F[3] = 2
F[4] = 0
匹配过程如下:
i = 0
和j = 0
S0 = a
和P0 = a
,则i = 1
和j = 1
S1 = b
和P1 = b
,则i = 2
和j = 2
S2 = c
和P2 = c
,则i = 3
和j = 3
S3 = a
和P3 = a
,则i = 4
和j = 4
S4 = b
和P4 = b
,则i = 5
和j = 5
S5 = d
和P5 = c
,则j = F[4] = 0
S5 = d
和P0 = a
,则i = 1
和j = 1
S6 = a
和P1 = b
,则j = F[0] = 0
S6 = a
和P0 = a
,则i = 2
和j = 1
S7 = b
和P1 = b
,则i = 3
和j = 2
S8 = c
和P2 = c
,则i = 4
和j = 3
S9 = a
和P3 = a
,则i = 5
和j = 4
S10 = b
和P4 = b
,则i = 6
和j = 5
S11 = c
和P5 = c
,则匹配成功
因此,KMP 算法在 S
中找到了模式串 P
。