Skip to content

Commit 9cd780c

Browse files
committed
add BF & BM algo in golang
1 parent a23f78b commit 9cd780c

File tree

3 files changed

+170
-152
lines changed

3 files changed

+170
-152
lines changed

go/31_graph/grap_search.go

Lines changed: 0 additions & 152 deletions
This file was deleted.

go/32_string/string_bf.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
)
6+
7+
//BF search pattern index, return the first match subs start index
8+
func bfSearch(main string, pattern string) int {
9+
10+
//defensive
11+
if len(main) == 0 || len(pattern) == 0 || len(main) < len(pattern) {
12+
return -1
13+
}
14+
15+
for i := 0; i <= len(main)-len(pattern); i++ {
16+
subStr := main[i : i+len(pattern)]
17+
if subStr == pattern {
18+
return i
19+
}
20+
}
21+
22+
return -1
23+
}
24+
25+
func main() {
26+
27+
main := "abcd227fac"
28+
pattern := "ac"
29+
fmt.Println(bfSearch(main, pattern))
30+
}

go/32_string/string_bm.go

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"math"
6+
)
7+
8+
//bc: pattern char index hash mapping
9+
func generateBC(pattern string) []int {
10+
11+
bc := make([]int, 256)
12+
13+
for index := range bc {
14+
bc[index] = -1
15+
}
16+
17+
for index, char := range pattern {
18+
bc[int(char)] = index
19+
}
20+
21+
return bc
22+
}
23+
24+
//generate suffix and prefix array for pattern
25+
func generateGS(pattern string) ([]int, []bool) {
26+
m := len(pattern)
27+
suffix := make([]int, m)
28+
prefix := make([]bool, m)
29+
30+
//init
31+
for i := 0; i < m; i++ {
32+
suffix[i] = -1
33+
prefix[i] = false
34+
}
35+
36+
for i := 0; i < m-1; i++ {
37+
j := i
38+
k := 0
39+
for j >= 0 && pattern[j] == pattern[m-1-k] {
40+
j--
41+
k++
42+
suffix[k] = j + 1
43+
}
44+
45+
if j == -1 {
46+
prefix[k] = true
47+
}
48+
}
49+
50+
return suffix, prefix
51+
}
52+
53+
//todo
54+
func moveByGS(patternLength int, badCharStartIndex int, suffix []int, prefix []bool) int {
55+
56+
//length of good suffix
57+
k := patternLength - badCharStartIndex - 1
58+
59+
//complete match
60+
if suffix[k] != -1 {
61+
return badCharStartIndex + 1 - suffix[k]
62+
}
63+
64+
//partial match
65+
for t := patternLength - 1; t > badCharStartIndex+1; t-- {
66+
if prefix[t] {
67+
return t
68+
}
69+
}
70+
71+
//no match
72+
return patternLength
73+
74+
}
75+
76+
func bmSearch(main string, pattern string) int {
77+
//defensive
78+
if len(main) == 0 || len(pattern) == 0 || len(pattern) > len(main) {
79+
return -1
80+
}
81+
82+
bc := generateBC(pattern)
83+
suffix, prefix := generateGS(pattern)
84+
85+
n := len(main)
86+
m := len(pattern)
87+
88+
// i : start index of main string
89+
step := 1
90+
for i := 0; i <= n-m; i = i + step {
91+
subStr := main[i : i+m]
92+
k, j := findBadChar(subStr, pattern, bc)
93+
94+
stepForBC := j - k
95+
//j is bad char occur index
96+
if j == -1 {
97+
return i
98+
}
99+
100+
stepForGS := -1
101+
if j < m-1 {
102+
stepForGS = moveByGS(m, j, suffix, prefix)
103+
}
104+
105+
//k is bad char index in pattern
106+
step = int(math.Max(float64(stepForBC), float64(stepForGS)))
107+
}
108+
109+
return -1
110+
}
111+
112+
func findBadChar(subStr string, pattern string, bc []int) (int, int) {
113+
114+
j := -1
115+
k := -1
116+
badChar := rune(0)
117+
118+
for index := len(subStr) - 1; index >= 0; index-- {
119+
if subStr[index] != pattern[index] {
120+
j = index
121+
badChar = rune(subStr[index])
122+
break
123+
}
124+
}
125+
126+
//if bad character exist, then find it's index at pattern
127+
if j > 0 {
128+
k = bc[int(badChar)]
129+
}
130+
131+
return k, j
132+
}
133+
134+
func main() {
135+
136+
main := "abcacabcbcabcabc"
137+
pattern := "cabcab"
138+
139+
fmt.Println(bmSearch(main, pattern))
140+
}

0 commit comments

Comments
 (0)