代码随想录刷题营Day9(28:strStr KMP算法)
28:strStr:
这道题目是典型的KMP算法来解题的,很经典。
KMP算法是用来干嘛的:
KMP算法是用来解决模式串在文本串中快速匹配问题的。
给定一个文本串:aabaabaaf
一个模式串:aabaaf
看文本串中是否包含模式串,并且快速进行匹配。
前缀和后缀的定义是什么:
前缀:是指在一个字符串中,不包含最后一个字符的前面的所有的字串
后缀:是指在一个字符串中,不包含第一个字符的后面的所有字串。
Next数组在找什么:最大相等前后缀
模式串aabaaf为例:
a:0
aa:1
aab:0
aaba:1
aabaa:2
aabaaf:0
那么aabaaf的最大相等前后缀数目:就是要看f前面的的aabaa的计算数值也就是2(也就是f前面a对应的)
所以,这样就得到了aabaaf的Next数组[0,1,0,1,2,0]
然后使用这个Next数组进行优化匹配速度:使其能够快速匹配到已经匹配的位置。(应用场景:如果找到不同的字符,就不再从头开始匹配,二十借助这个不匹配的字符前面的字符对应的下标,从这个下标值下开始进行匹配,如果这个下标不等于0的话,那就可以实现匹配的就会快一点,如果是0,就跟往常一样)
不知道可不可以这么理解,KMP算法就是再找模式串中的蕴含的小规律,来实现快速匹配算法,如果Next都是零的话,就跟从头再来一遍没啥区别了。
Next数组有三种算法:
Next数组有三种算法:以上面举的例子为例,
- 正常版:就跟上述计算方式一样,[0,1,0,1,2,0]
- 求出正常版,然后再右移正常版[-1,0,1,0,1,2],这样第一个值就置为-1,这样搞得好处就是,遇到不匹配的,直接找他当下的下标作为重新开始匹配的点即可。
- 得到正常版之后,在正常版的基础上,整体减一,得到[-1,0,-1,0,1,-1],呃呃,为啥这样干我给忘记了,明天再看看。
求Next数组的代码:
def getNext(m):
next_=[0]*len(m)
next_[0]=0
j=0
for i in range(1,len(m)):
while(j>0 and m[i]!=m[j]):
j=next_[j-1]
if m[i]==m[j]:
j=j+1
next_[i]=j
return next_
值得注意的是:如何让理解定义的 i 和 j 。
i 比较好理解就是遍历一遍字符串,拿到遍历的索引。
j 是指当前字符串m[0:i]的最大前后缀的长度或者说是最大前缀的下标。
正如代码中写的,一旦发现m[i]!=m[j]了,那就j需要返回next[j-1]的值。并且是while不断返回,这里只写if,返回一次是不够的,一定要注意!
太晚了,明天再重新敲一遍,巩固一下!
觉得刷这个第二遍就是不一样,明显觉得自己理解的透彻了一点,不知道过几天我会不会有都忘了。。。