KMP匹配字符串时,如果匹配字符失败了,并不从头再匹配,而是回溯到一个特定的位置,这个位置和需要匹配的字符串有关,用next数组记录匹配每个位置失败时要回溯的位置。这样就能减少回溯和匹配的次数,从而提高计算效率。
计算next数组:
def GetNext(s:str)->list: n = len(s) k = 0 Next = [-1]#首个匹配失败会返回-1 for i in range(1,n):#从第二个字符开始匹配 Next.append(k)#s[i]匹配失败就回溯到s[k],再开始匹配 while k!=-1 and s[k]!=s[i]:#如果s[k]和s[i]相同,那么k无需回退 k = Next[k]#如果不同,将k回退到s[k]匹配失败要回退的位置,直到k==-1,或者s[k]==s[i] k+=1 return Next
这个过程就像需要0匹配的字符串自己和自己匹配,也叫字符串的自匹配。
下面举个例子:
然后是kmp比较的函数:
def KmpLocation(s1:str,s2:str)->int:#s1为大字符串,s2位要被匹配的字符串 Next = GetNext(s2) n = len(s1)-len(s2)#字符串长度的差 j = 0 for i in range(0,len(s1)+1): if j == len(s2):#j指到s2的最后一个字符后面表示匹配成功 return i-j#返回匹配成功时s1的相应索引 if i==len(s1):#i已经指到了s1的最后一个字符串,但是j还没到s2的最后一个字符串 return -1#匹配失败 while j!=-1 and s1[i]!=s2[j]: j = Next[j] j+=1
相应的实例: