最长公共前后缀
就是在前后缀中取最大的相同缀。比如对于字符串"abab",其前缀有a、ab、aba,后缀有b、ab、bab,显然最长公共前后缀就是ab
构建next
next[i]储存了在以i为开头的后缀,和以j为结尾的前缀匹配时,j的下一个位置。正如next名字所暗示的,下一个,而不是匹配的j本身
之所以储存下一个的原因在于,在进行匹配时,模式串要跳到上一个匹配成功的位置,而字符串本身不会移动,那么在这种情况下,当前字符串要匹配的就是已经匹配成功字符的下一个位置
func getNext(pattern string) []int {
next := make([]int, len(pattern))
// i指向后缀的开始,j指向前缀的结尾
var j int
for i := 1; i < len(pattern); {
// 当i、j匹配时,那么在i不匹配时,就会直接跳到j的下一位,然后i、j同时向右移动,
// 在实际匹配时,如果模式串i与字符串不匹配,那么会直接使得模式串索引i直接跳到前一条匹配的位置的下一位
if pattern[i] == pattern[j] {
next[i] = j + 1
j++
i++
} else {
// 当i、j不匹配时,若j不在字符串头,那么j回退到上一个匹配的位置
// 若j在字符串头,i向右移动
if j != 0 {
j = next[j-1]
} else {
next[i] = 0
i++
}
}
}
return next
}
字符串匹配
在获取到next数组之后,就直接获取到了如果不匹配情况下,模式串该如何走
func KMP(text, pattern string) bool {
next := getNext(pattern)
var i, j int
for i < len(text) && j < len(pattern) {
// 如果匹配,那么i、j同时向右移动
if text[i] == pattern[j] {
i++
j++
continue
}
// 如果不匹配,那么j回退到上一个匹配的位置
if j != 0 {
j = next[j-1]
} else {
i++
}
}
return j == len(pattern)
}
本文介绍了如何使用KMP算法解决字符串匹配问题,重点讲解了最长公共前后缀的概念以及next数组的构建过程,这对于处理不完全匹配的字符串搜索至关重要。
9万+

被折叠的 条评论
为什么被折叠?



