今天刷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
下一篇,讨论代码