朴素的模式匹配算法
一个例子:
从主串 S = "goodjob"中,找到子串 T = "job"的位置。我们通常需要下面的步骤。
1. 将子串"job"与主串S从第一位对应匹配。即判断 whether 'g' == 'j';
2. 判断结果为否,继续匹配 whether 'o' == 'j';
3. 直到找到第一位匹配 'j' = 'j';
4. 继续匹配完整 S[4:7] == 'job' == T。
是一种最简单的匹配算法,暴力易实现,但有许多冗余的步骤。
KMP 模式匹配算法
总的思想是:通过字符串已有的信息来规避朴素模式匹配中可以省略的步骤。
详细的过程不再赘述,在这里只进行简要的说明。
已知主串的下标为 i i i, 子串的下标为 j j j, 总结下来是两短句:“ i i i 不回溯, j j j 依 n e x t next next”。
i i i 不回溯:指的是在匹配过程中,主串的匹配下标永远只会增加或不变,不会再去匹配之前主串的下标。
j j j 依 n e x t next next:指的是子串的下标匹配规则是依照 n e x t next next 数组值。
那么下面要详细说明 n e x t next next 数组值是什么。
n e x t next next 数组值推导
先给出数学式的定义:
n e x t [ j ] = { 0 , 当 j = 1时 M a x { k ∣ 1 < k < j , 且 ′ p 1 . . . p k − 1 ′ = ′ p j − k + 1 . . . p j − 1 ′ } 当 此 集 合 不 空 时 1 , 其他情况 next[j] = \begin{cases} 0, & \text{当 j = 1时} \\[2ex] Max\{ k | 1<k<j,且'p_1 ...p_{k-1}' ='p_{j-k+1}...p_{j-1}'\}& \text当此集合不空时\\[2ex] 1, & \text{其他情况} \end{cases} next[j]=⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧0,Max{
k∣1<k<j,且′p1...pk−1′=′pj−k+1...pj−1′}1,当 j = 1时当此集合不空时其他情况
e.g. T = “abcabx”
j 123456 模 式 串 T a b c a b x n e x t [ j ] 011123 \begin{array}{c|lcr} j & 123456 \\ \hline 模式串T & abcabx \\ next[j] & 011123 \end{array} j模式串Tnext[j]123456abcabx011123
其中的一个子串"abcab", abcab,前缀和后缀有两个字符相等,则 n e x t [ 6 ] = 2 + 1 = 3 next[6] = 2 + 1 = 3 next[6]=2+1=3。
整个算法的时间复杂度时 O(n + m),相较于朴素模式匹配算法的 O((n - m + 1) * m)来说,较好一些(T的长度为m)。
KMP模式匹配算法改进
一个例子:主串S = “aaaabcde”,子串T = “aaaaax”,其 next 数组值分别为 012345,在开始时,当 i = 5, j = 5时,我们发现"b" 与 "a"不想等,因此,j = next[5] = 4,此时 "b"与第四位置的"a"依然不等,j = next[4] = 3 … 这样也会多出很多冗余的步骤。所以,我们对求解next函数进行了改进。
在每次赋值next的时候增加一个判断,判断 w h e t h e r T [ i ] = = T [ j ] whether\ T[i] == T[j] whether T[i]==T[j]。
最后给出具体的python求解next数组的程序:
import numpy as np
def get_nextval(T):
T = '#' + T
i = 1
j = 0
nextval = np.zeros(len(T), dtype=int)
while i < len(T)-1:
if j == 0 or T[i] == T[j]:
i = i + 1
j = j + 1
if T[i] != T[j]:
nextval[i] = j
else:
nextval[i] = nextval[j]
else:
j = nextval[j]
nextval = np.delete(nextval,0)
return nextval
− − − − − − − − − − − − − − − − ---------------- −−−−−−−−−−−−−−−−
该文章首发于 zyairelu.cn
欢迎来到我的网站进行评论及研讨
个人邮箱[email protected]
− − − − − − − − − − − − − − − − ---------------- −−−−−−−−−−−−−−−−