Skip to content

Commit

Permalink
add BF & BM algo in golang
Browse files Browse the repository at this point in the history
  • Loading branch information
LYDongD committed Dec 9, 2018
1 parent a23f78b commit 9cd780c
Show file tree
Hide file tree
Showing 3 changed files with 170 additions and 152 deletions.
152 changes: 0 additions & 152 deletions go/31_graph/grap_search.go

This file was deleted.

30 changes: 30 additions & 0 deletions go/32_string/string_bf.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package main

import (
"fmt"
)

//BF search pattern index, return the first match subs start index
func bfSearch(main string, pattern string) int {

//defensive
if len(main) == 0 || len(pattern) == 0 || len(main) < len(pattern) {
return -1
}

for i := 0; i <= len(main)-len(pattern); i++ {
subStr := main[i : i+len(pattern)]
if subStr == pattern {
return i
}
}

return -1
}

func main() {

main := "abcd227fac"
pattern := "ac"
fmt.Println(bfSearch(main, pattern))
}
140 changes: 140 additions & 0 deletions go/32_string/string_bm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
package main

import (
"fmt"
"math"
)

//bc: pattern char index hash mapping
func generateBC(pattern string) []int {

bc := make([]int, 256)

for index := range bc {
bc[index] = -1
}

for index, char := range pattern {
bc[int(char)] = index
}

return bc
}

//generate suffix and prefix array for pattern
func generateGS(pattern string) ([]int, []bool) {
m := len(pattern)
suffix := make([]int, m)
prefix := make([]bool, m)

//init
for i := 0; i < m; i++ {
suffix[i] = -1
prefix[i] = false
}

for i := 0; i < m-1; i++ {
j := i
k := 0
for j >= 0 && pattern[j] == pattern[m-1-k] {
j--
k++
suffix[k] = j + 1
}

if j == -1 {
prefix[k] = true
}
}

return suffix, prefix
}

//todo
func moveByGS(patternLength int, badCharStartIndex int, suffix []int, prefix []bool) int {

//length of good suffix
k := patternLength - badCharStartIndex - 1

//complete match
if suffix[k] != -1 {
return badCharStartIndex + 1 - suffix[k]
}

//partial match
for t := patternLength - 1; t > badCharStartIndex+1; t-- {
if prefix[t] {
return t
}
}

//no match
return patternLength

}

func bmSearch(main string, pattern string) int {
//defensive
if len(main) == 0 || len(pattern) == 0 || len(pattern) > len(main) {
return -1
}

bc := generateBC(pattern)
suffix, prefix := generateGS(pattern)

n := len(main)
m := len(pattern)

// i : start index of main string
step := 1
for i := 0; i <= n-m; i = i + step {
subStr := main[i : i+m]
k, j := findBadChar(subStr, pattern, bc)

stepForBC := j - k
//j is bad char occur index
if j == -1 {
return i
}

stepForGS := -1
if j < m-1 {
stepForGS = moveByGS(m, j, suffix, prefix)
}

//k is bad char index in pattern
step = int(math.Max(float64(stepForBC), float64(stepForGS)))
}

return -1
}

func findBadChar(subStr string, pattern string, bc []int) (int, int) {

j := -1
k := -1
badChar := rune(0)

for index := len(subStr) - 1; index >= 0; index-- {
if subStr[index] != pattern[index] {
j = index
badChar = rune(subStr[index])
break
}
}

//if bad character exist, then find it's index at pattern
if j > 0 {
k = bc[int(badChar)]
}

return k, j
}

func main() {

main := "abcacabcbcabcabc"
pattern := "cabcab"

fmt.Println(bmSearch(main, pattern))
}

0 comments on commit 9cd780c

Please sign in to comment.