KMP算法小结
1. 优点
令待匹配字符串长度为 n n n,模式串长度为 m m m
因为使用模式串前缀和后缀信息,能够在 O ( m + n ) O(m+n) O(m+n)的时间复杂度内,完成字符串的匹配
2. next数组定义
2.1 寻找前缀后缀最长公共元素长度
2.2 求next数组
next数组考虑的是除当前字符外的最长相同前缀后缀;因此,可以将最长相同前缀后缀右移一位,初值赋值为-1
2.3 根据next数据进行匹配
如果 S i S_i Si和 P j P_j Pj没有匹配成功,将模式串的第 k + 1 k+1 k+1位置对齐到 S i S_i Si,即将模式串移动 j − n e x t [ j ] j-next[j] j−next[j]位
2.4 next数组意义
next[j] = k 代表p[j] 之前的模式串子串中,有长度为k 的相同前缀和后缀 有了这个next 数组,在KMP匹配中,当模式串中j 处的字符失配时,下一步用next[j]处的字符继续跟文本串匹配,相当于模式串向右移动j - next[j] 位。
3. KMP算法实现
代码
- 语言支持:Python3
Python3 Code:
from typing import List
class Solution:
def strStr(self, haystack: str, needle: str) -> int:
next = self.GetNext(needle)
i,j = 0,0
s_n,p_n = len(haystack),len(needle)
while i < s_n and j < p_n:
if j == -1 or haystack[i] == needle[j]:
i+=1
j+=1
else:
j = next[j]
if j == p_n:
return i-j
else:
return -1
def GetNext(self,needle:str)->List:
if not needle:
return None
k,j = -1,0
n = len(needle)
# next[0]默认为-1
next = [-1] * n
# j从0遍历到n-2,后面会先j+=1,因此j从1到n-1
while j < n-1:
if k==-1 or needle[k] == needle[j]:
j += 1
k += 1
# 优化next数组
if needle[j] != needle[k]:
next[j] = k
else:
next[j] = next[k]
else:
k = next[k]
return next
Reference:
- https://blog.csdn.net/v_JULY_v/article/details/7041827