时间复杂度是O(m+n),n是模式串长度、m是主串长度。空间复杂度O(n),因为失效函数借助了一个数组长度为n
重点
- 比较的移动借鉴了BM算法,采用好前缀规则如图,遇到坏字符时候,假设好前缀的最长可匹配前缀子串长度为v,则模式串一次性移动j-v个距离,相当于将j变为v
- 求解失效数组
匹配代码
1 | func KMP(str string, ptr string) int { |
求解next数组代码
规律如下,假设模式串为a,那么遵循如下俩条规律
- 当a[0,i-1]的最长可匹配前子串是a[0,k-1],的下一个字符a[i]等于a[k],那么a[0,i]的最长匹配前缀就是a[0,k]
- 当a[i]不等于a[k],我们要找到a[0,i-1]的次长匹配子串a[0,k’],当a[k’+1]等于a[i],那么a[0,k’]就是a[0,i]的最长匹配前缀
- 其中,a[0,k’]一定包含a[0,k-1]中,即next数组中,如图
1 |
|