1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
package main
import (
"fmt"
)
func main() {
haystack := "hello"
needle := "ll"
hay := []rune(haystack)
need := []rune(needle)
var halen = len(haystack)
var nelen = len(needle)
n := bm(hay, need, halen, nelen)
fmt.Println(n) // 2
}
func badChar(b []rune, m int) (bc []int) {
bc = make([]int, 256)
var i int
for i < 256 { // charset
bc[i] = -1
i++
}
i = 0
for i < m {
var ascii = b[i]
bc[ascii] = i
i++
}
return
}
func goodSuffix(b []rune, m int) (suffix []int, prefix []bool) {
suffix = make([]int, m)
prefix = make([]bool, m)
var i int
for i < m {
suffix[i] = -1
//prefix[i] = false
i++
}
i = 0
for i < (m - 1) {
var j = i
var k = 0
for j >= 0 && (b[j] == b[m-1-k]) {
k++
suffix[k] = j + 1
j--
}
if j == -1 {
prefix[k] = true
}
i++
}
return
}
func bm(a, b []rune, n, m int) int {
bc := badChar(b, m)
suffix_index, ispre := goodSuffix(b, m)
var i = 0
var j int
for i <= (n - m) {
j = 0
//从后往前匹配,找到坏字符
for j = m - 1; j >= 0; {
if a[i+j] != b[j] {
break
}
j--
}
//匹配成功
if j < 0 {
return i
}
//求坏字符规则下移动位数
var x = j - bc[a[i+j]]
var y int
if y < (m-1) && (m-1-j) > 0 {
y = move(j, m, suffix_index, ispre)
}
//移动
if x >= y {
i += x
} else {
i += y
}
}
return -1
}
// j代表坏字符的下标
func move(j, m int, suffix_index []int, ispre []bool) int {
//好后缀长度
var k = m - 1 - j
//如果含有长度为k的好后缀,返回移动位数
if suffix_index[k] != -1 {
return j - suffix_index[k] + 1
}
//找头部为好后缀子串的最大长度,从长度最大的子串开始
for r := j + 2; r <= m-1; {
//如果是头部
if ispre[m-r] {
return r
}
r++
}
//没有好后缀,或头部为好后缀子串,返回匹配串长度m
return m
}
|