KMP
序列aabaabaabksse,是否包含子序列aabaabk
经典算法
从左到右,每个字符当作开头,看是否匹配aabaabk
1.从0开始比对
2.当匹配到第六个字符k,发现不相等,主指针跳回0+1,子指针跳回0
2.从1开始比对,发现不相等跳到1+1
3.直到主指针从3开始,找到相等,返回3
KMP算法
aabaab的最大前缀是指找到一个最大的数n,从左往右取n个字符==从右往左取n个字符,n不能等于字符串长度
aab==aab ,n=3
记录子序列的aabaabk每个位置的最大前缀
next =[-1,0,1,0,1,2,3]
1.从0开始比对,当匹配到子序列aabaabk第六个字符k时不相等
2.经典算法中,主序列需要跳回到1的位置从头开始比对
这里拿到next[6]=3,主序列不动,子序列从第六个跳到next[6]的位置,继续比对
完成加速
3.当子指针遍历完时,退出循环,返回index=主-子
func getIndexOf(s, m string) int {
if len(s) == 0 || len(m) == 0 || len(m) < 1 || len(s) < len(m) {
return -1
}
str1 := strings.Split(s, "")
str2 := strings.Split(m, "")
i1 := 0
i2 := 0
var next []int = getNextArray(str2)
for i1 < len(str1) && i2 < len(str2) {
if str1[i1] == str2[i2] {
i1++
i2++
} else {
if i2 == 0 {
i1++
} else {
i2 = next[i2]
}
}
}
if i2 == len(str2) {
return i1 - i2
} else {
return -1
}
}
func getNextArray(str []string) []int {
if len(str) == 1 {
return []int{-1}
}
next := make([]int, len(str))
next[0] = -1
next[1] = 0
i := 2
cn := 0
for i < len(next) {
if str[i-1] == str[cn] {
cn++
next[i] = cn
i++
} else if cn > 0 {
cn = next[cn]
} else {
next[i] = 0
i++
}
}
return next
}