📅  最后修改于: 2023-12-03 15:02:31.668000             🧑  作者: Mango
KMP算法是一种字符串匹配算法,可以用于在一个主串中查找一个模式串的出现位置。KMP算法的核心思想是在模式串匹配失败时,尽可能地利用已经匹配成功的前缀信息,快速定位下一次匹配的位置。
KMP算法通过跳过已经匹配成功的前缀,来减少匹配次数。在匹配过程中,如果在模式串的某个位置匹配失败,KMP算法会尝试利用已经匹配成功的前缀信息,找到下一个可以尝试匹配的位置。从而减少匹配次数,提高匹配效率。
举个例子:
假设我们要在字符串ABABACABABC
中查找ABABC
这个模式串,下面是KMP算法的匹配过程:
A
与主串的第一个字符A
匹配成功。B
与主串的第二个字符B
匹配成功。A
与主串的第三个字符A
匹配成功。但是,模式串的第四个字符B
与主串的第四个字符C
不匹配,这个时候,KMP算法会尝试利用已经匹配成功的前缀信息来找到下一个可以尝试匹配的位置。AB
是ABABC
的前缀,而模式串的第一个字符是A
,所以下一个可以尝试匹配的位置是模式串中的第二个字符,即B
。AB
,而模式串的第一个字符也是A
,所以下一个可以尝试匹配的位置是主串中的第四个字符,即A
。B
与主串的第五个字符B
匹配成功。A
与主串的第六个字符A
匹配成功。B
与主串的第七个字符B
匹配成功。C
与主串的第八个字符C
匹配成功。ABABC
的出现位置为4。下面是KMP算法的实现代码:
def get_next(p):
next = [-1] * len(p)
i, j = 0, -1
while i < len(p) - 1:
if j == -1 or p[i] == p[j]:
i, j = i + 1, j + 1
next[i] = j
else:
j = next[j]
return next
def kmp(s, p):
next = get_next(p)
i, j = 0, 0
while i < len(s) and j < len(p):
if j == -1 or s[i] == p[j]:
i, j = i + 1, j + 1
else:
j = next[j]
if j == len(p):
return i - j
else:
return -1
这段代码中,get_next
函数用于计算模式串的next
数组,而kmp
函数用于在主串中查找模式串的出现位置。具体实现时,我们用i
来表示主串中当前尝试匹配的位置,用j
来表示模式串中当前尝试匹配的位置。如果当前匹配成功,则让i
和j
分别加1;否则,将j
更新为next[j]
(即尝试利用已经匹配成功的前缀信息来快速定位下一个可以尝试匹配的位置)。匹配成功的条件是整个模式串都已经匹配成功,此时返回模式串在主串中的起始位置,否则返回-1。