KMP算法golang实现

     KMP具体讲解就不说了,我讲得肯定没有网上的各位大神好,这里我找到一篇讲得比较好的,通俗易懂的。可以参考下:http://wiki.jikexueyuan.com/project/kmp-algorithm/define.html

 

直接上代码,难懂的地方我稍微注释了下。

//传统next数组
func getNext(p string) []int {

	pLen := len(p)
	next := make([]int, pLen, pLen)
	next[0] = -1
	next[1] = 0
	i := 0
	j := 1
	for j < pLen-1 { //因为next[pLen-1]由s[i] == s[pLen-2]算出
		if i == -1 || p[i] == p[j] { //-1代表了起始位不匹配,i=0,s[0]!=s[j]=>i=next[0]=-1
			i++
			j++
			next[j] = i
		} else {
			i = next[i]
		}
	}
	return next
}

//优化next数组
func getNextOptimize(p string) []int {
	pLen := len(p)
	next := make([]int, pLen, pLen)
	next[0] = -1
	next[1] = 0
	i := 0
	j := 1
	for j < pLen-1 { //因为next[pLen-1]由s[i] == s[pLen-2]算出
		if i == -1 || p[i] == p[j] { //-1代表了起始位不匹配,i=0,s[0]!=s[j]=>i=next[0]=-1
			i++
			j++
			if p[i] != p[j] { //因为出现在j位置不匹配的话会跳到next[j]=i位置去匹配,p[i] == p[j]肯定又是不匹配(优化核心点)
				next[j] = i
			} else {
				next[j] = next[i]
			}

		} else {
			i = next[i]
		}
	}
	return next
}

/*为何不匹配时i=next[i]?

__________________i----____________j
****next[i]___****i----________****j

由next[j] = i知道_____和_____相等
由next[i]知道****相等
所以不匹配时i先回溯到next[i]位置
*/

func KmpSearch(s, p string) int {
	i, j := 0, 0
	pLen := len(p)
	sLen := len(s)
	next := getNext(p)
	for i < sLen && j < pLen {
		if j == -1 || s[i] == p[j] { //s[i]!=s[0]=>j=next[0]=-1,第0位不匹配所以i++,j++;j=0
			i++
			j++
		} else {
			j = next[j]
		}
	}
	if j == pLen {
		return i - j
	} else {
		return -1
	}

}

 

你可能感兴趣的:(KMP算法golang实现)