今天刷leetcode,发现28-实现strStr()这道题,可以使用KMP算法实现,所以去百度了一翻,做个记录。

KMP算法简介:是一种改进的字符串匹配算法。

核心思想:通过匹配失败后的信息,尽量减少模式串与主串的匹配次数来达到快速匹配的目的。

leetcode题目:给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回  -1。

1.自己写的算法:

假设 haystack 为  BBC ABCDAB ABCDABCDABDE

        needle   为   ABCDABD

思路:haystack 的下标为i,needle 的下标为j,当haystack .charAt(i)==needle .charAt(j)时,比较haystack i+1和needle j+1的值,如果都相同,那么返回下标

2.KMP算法:

该算法是对上述情况的优化,假设当i=4时,haystack 为   BBC ABCDABEABCDABCDABDE  ,此时' '!='D',那么就要进行下次比较,i++,一直到i=8

              i=4     needle    为          ABCDABD

              i=8     needle    为                 ABCDABD

当i=4时,haystack 截取needle长度的字串为“ABCDABE”,然后一直判定到i=10时失败,然后开始i++,一直到i=8,为什么会到i=8??

因为此时‘AB’=‘AB’,那么下一步比较'E' 'C'了,C的下标为'2',正好为“ABCDAB”的最大模式字串的长度,此时i=10,j=2。

那么我们是不是可以说,当j=k时,haystack [i] ! =needle[k],正好当j=k-1时,截取0到k-1的最大模式字串的长度为2,我们就可以令i不变,j=3,

省略到其中i++

 

总结来说,在i=k处,2个字符串的第一个字节相等,然后依次判断下一个字节,当i=k+m时,判定失败,那么我们就要知道needle在m-1处的最大模式字串的长度,

其实最大模式字串的长度就是下一次就行效验的下标

上面的例子,i=10 j=6时,判断失败,j=5时的最大模式字串长度为2,那么我们下次判断,i=10 j=2,即 ‘ ’ 和‘C’判断是否相等

那么我们就要求next 函数返回的数组,a[j]=上一个索引所对应的最大模式字串长度

那么此时,我们需要求一下,needle    中每个下标的最大模式字串

那么对应的长度为,0  0  0  0  1  2  0

下一篇,讨论代码