Skip to content

Commit 30a851f

Browse files
committed
add kmp
1 parent 533f714 commit 30a851f

File tree

3 files changed

+100
-0
lines changed

3 files changed

+100
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ To test each algorithm(data structure), instead of running the file directly, yo
7777
* [Quick3string](algs4/quick3_string.go)
7878
* [TrieST](algs4/trie_st.go)
7979
* [TST](algs4/tst.go)
80+
* [KMP](algs4/kmp.go)
8081

8182

8283
## License

algs4/kmp.go

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package algs4
2+
3+
// KMP ...
4+
type KMP struct {
5+
pattern string
6+
dfa [][]int
7+
}
8+
9+
// makeTwoD return a two dimensional slice
10+
func makeTwoD(rows, columns int) [][]int {
11+
twoD := make([][]int, rows)
12+
for i := 0; i < rows; i++ {
13+
twoD[i] = make([]int, columns)
14+
}
15+
return twoD
16+
}
17+
18+
// NewKMP ...
19+
func NewKMP(pattern string) *KMP {
20+
R := 256
21+
M := len(pattern)
22+
dfa := makeTwoD(R, M)
23+
k := &KMP{pattern, dfa}
24+
dfa[pattern[0]][0] = 1
25+
X := 0
26+
for j := 1; j < M; j++ {
27+
for c := 0; c < R; c++ {
28+
dfa[c][j] = dfa[c][X]
29+
}
30+
dfa[pattern[j]][j] = j + 1
31+
X = dfa[pattern[j]][X]
32+
}
33+
return k
34+
}
35+
36+
// Search ...
37+
func (k *KMP) Search(txt string) int {
38+
N, M := len(txt), len(k.pattern)
39+
var i, j int
40+
for i, j = 0, 0; i < N && j < M; i++ {
41+
j = k.dfa[txt[i]][j]
42+
}
43+
// Found (hit end of pattern)
44+
if j == M {
45+
return i - M
46+
}
47+
// Not Found (hit end of text)
48+
return N
49+
}

cmd/kmp/main.go

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/******************************************************************************
2+
* Execution: go run cmd/kmp/main.go pattern text
3+
*
4+
* Reads in two strings, the pattern and the input text, and
5+
* searches for the pattern in the input text using the
6+
* KMP algorithm.
7+
*
8+
* % go run cmd/kmp/main.go abracadabra abacadabrabracabracadabrabrabracad
9+
* text: abacadabrabracabracadabrabrabracad
10+
* pattern: abracadabra
11+
*
12+
* % go run cmd/kmp/main.go rab abacadabrabracabracadabrabrabracad
13+
* text: abacadabrabracabracadabrabrabracad
14+
* pattern: rab
15+
*
16+
* % go run cmd/kmp/main.go bcara abacadabrabracabracadabrabrabracad
17+
* text: abacadabrabracabracadabrabrabracad
18+
* pattern: bcara
19+
*
20+
* % go run cmd/kmp/main.go rabrabracad abacadabrabracabracadabrabrabracad
21+
* text: abacadabrabracabracadabrabrabracad
22+
* pattern: rabrabracad
23+
*
24+
* % go run cmd/kmp/main.go abacad abacadabrabracabracadabrabrabracad
25+
* text: abacadabrabracabracadabrabrabracad
26+
* pattern: abacad
27+
*
28+
******************************************************************************/
29+
30+
package main
31+
32+
import (
33+
"fmt"
34+
"os"
35+
36+
"github.com/shellfly/algo/algs4"
37+
)
38+
39+
func main() {
40+
pat, txt := os.Args[1], os.Args[2]
41+
kmp := algs4.NewKMP(pat)
42+
offset := kmp.Search(txt)
43+
fmt.Println("offset: ", offset)
44+
fmt.Println("text: " + txt)
45+
fmt.Print("pattern: ")
46+
for i := 0; i < offset; i++ {
47+
fmt.Print(" ")
48+
}
49+
fmt.Println(pat)
50+
}

0 commit comments

Comments
 (0)