马拉车算法 kmp golang 版本
暴力破解版
func voKmp(txt, pat string) int {
n := len(txt)
m := len(pat)
for i := 0; i < n-m; i++ {
j := 0
for j = 0; j < m; j++ {
if pat[j] != txt[i+j] {
break
}
}
if j == m {
return i
}
}
return -1
}
马拉车 不走回头路 记录已经匹配的相同前缀
- 使用有限确定状态机
func kmp(pat string) [][]int {
m := len(pat)
dp := make([][]int, m)
dp[0] = make([]int, 256)
dp[0][int(pat[0])] = 1
x := 0
for j := 1; j < m; j++ {
dp[j] = make([]int, 256)
for c := 0; c < 256; c++ {
//if int(pat[j]) == c {
// dp[j][c] = int(j + 1)
//}else{
// dp[j][c] = int(dp[x][c])
//}
// 状态回退
dp[j][c] = int(dp[x][c])
}
// 转为下一个状态
dp[j][int(pat[j])] = int(j + 1)
// 更新相同前缀状态
x = dp[x][int(pat[j])]
}
return dp
}
实现查找
func search(txt, pat string, dp [][]int) int {
j := 0
m := len(pat)
n := len(txt)
for i := 0; i < n; i++ {
j = dp[j][int(txt[i])]
if j == m {
return i + 1 - m
}
}
return -1
}
验证
m := "aaab"
n := "aaacaaab"
fmt.Println(search(n, m, kmp(m)))
本文来自博客园,作者:vx_guanchaoguo0,转载请注明原文链接:https://www.cnblogs.com/guanchaoguo/p/16446851.html