add string match
This commit is contained in:
parent
a6c6435bc7
commit
6befec80e9
11
main.go
11
main.go
@ -1,6 +1,8 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
. "github.com/ehlxr/leetcode-go/src"
|
||||
)
|
||||
|
||||
@ -22,7 +24,12 @@ func main() {
|
||||
// rs := []rune(s)
|
||||
// println(string(rs[6]))
|
||||
|
||||
s := "babad"
|
||||
println(LongestPalindrome(s))
|
||||
// s := "babad"
|
||||
// println(LongestPalindrome(s))
|
||||
|
||||
s := "bacbababaabcbab"
|
||||
p := "ababa"
|
||||
// fmt.Printf("%+v\n", GetNext(p))
|
||||
fmt.Printf("%+v\n", Kmp(s, p))
|
||||
fmt.Printf("%+v", Bf(s, p))
|
||||
}
|
||||
|
89
src/string_match.go
Normal file
89
src/string_match.go
Normal file
@ -0,0 +1,89 @@
|
||||
package src
|
||||
|
||||
// 暴力匹配
|
||||
func Bf(s, p string) int {
|
||||
n := len(s)
|
||||
m := len(p)
|
||||
if n < m {
|
||||
return -1
|
||||
}
|
||||
|
||||
for i := 0; i <= n-m; i++ {
|
||||
j := 0
|
||||
for j < m {
|
||||
// 如果主串与模式串不匹配,则主串向右移动一个字符,模式串从头开始匹配
|
||||
if s[i+j] != p[j] {
|
||||
break
|
||||
}
|
||||
j++
|
||||
}
|
||||
if j == m {
|
||||
return i
|
||||
}
|
||||
}
|
||||
|
||||
return -1
|
||||
}
|
||||
|
||||
func Kmp(s, p string) int {
|
||||
n := len(s)
|
||||
m := len(p)
|
||||
if n < m {
|
||||
return -1
|
||||
}
|
||||
next := GetNext(p)
|
||||
|
||||
for i := 0; i <= n-m; i++ {
|
||||
j := 0
|
||||
for j < m {
|
||||
// 暴力匹配算法当模式串和主串不匹配时,主串匹配下标 +1,模式串匹配下标置为 0,
|
||||
// KMP 算法优化点在于将模式串下标置为不匹配字符前一个字符对应 next 数组的值
|
||||
if s[i+j] != p[j] {
|
||||
// 当模式串与主串不匹配时,如果不匹配字符对应模式串下标大于 j > 0 (非首个模式串字符),
|
||||
// 并且此字符前一个字符对应字符串部分匹配表中的值 next[j - 1] 也大于 0,
|
||||
// j - next[j - 1] 即模式串为后移的位数,等价于 j 置为 next[j - 1]
|
||||
|
||||
if j != 0 && next[j-1] != 0 {
|
||||
// j 后移 j-next[j-1],等价于 j = next[j-1]
|
||||
j = next[j-1]
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
j++
|
||||
}
|
||||
if j == m {
|
||||
return i
|
||||
}
|
||||
}
|
||||
|
||||
return -1
|
||||
}
|
||||
|
||||
func GetNext(p string) []int {
|
||||
n := len(p)
|
||||
next := make([]int, n)
|
||||
next[0] = 0
|
||||
k := 0
|
||||
|
||||
// 根据已知 next 数组的前 i-1 位推测第 i 位
|
||||
for i := 1; i < n; i++ {
|
||||
for k > 0 && p[k] != p[i] {
|
||||
// k 为 p[0, i) 子串最大匹配前后缀长度
|
||||
// p[0, k) 为 p[0, i) 子串最大匹配前缀子串
|
||||
|
||||
// 若:1、p[k] != p[i],则求 p[0, i] 子串最大匹配前后缀长度问题
|
||||
// 转换成了求 p[0, k) 子串最大匹配前后缀长度问题
|
||||
// 循环直到 p[k] == p[i] (下一步处理) 或 k == 0
|
||||
k = next[k]
|
||||
}
|
||||
|
||||
// 若:2、p[k] == p[i],则 p[0, i] 子串最大匹配前后缀长度为 k + 1
|
||||
if p[k] == p[i] {
|
||||
k++
|
||||
}
|
||||
|
||||
next[i] = k
|
||||
}
|
||||
return next
|
||||
}
|
Loading…
Reference in New Issue
Block a user