Last active
November 8, 2021 06:50
-
-
Save thanhpp/cd6f6fe8085c9c338325c8ce3507159e to your computer and use it in GitHub Desktop.
KMP matching
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
) | |
func Failure(s string) []int { | |
res := make([]int, len(s)) | |
for i := range s { | |
var max int | |
// build s[0,i] prefix | |
var prefixMap = make(map[string]struct{}) | |
for j := 0; j <= i; j++ { | |
prefix := s[0 : j+1] | |
prefixMap[prefix] = struct{}{} | |
} | |
// buid s[1,i] suffix and compare | |
for j := 0; j < i; j++ { | |
suffix := s[1+j : i+1] | |
if _, ok := prefixMap[suffix]; ok { | |
if len(suffix) > max { | |
max = len(suffix) | |
} | |
} | |
} | |
res[i] = max | |
} | |
return res | |
} | |
// search for t in p | |
func KMPMatch(t, p string) { | |
// build the failure array | |
f := Failure(p) | |
for i := range p { | |
fmt.Printf("%2c ", t[i]) | |
} | |
fmt.Println() | |
for i := range p { | |
fmt.Printf("%2d ", f[i]) | |
} | |
fmt.Println() | |
// start the algorithm | |
var i, j int = 0, 0 | |
for i < len(t) { | |
// if match | |
if t[i] == p[j] { | |
// if all p is matched | |
if j == len(p)-1 { | |
fmt.Println("match", i-j) | |
i = i + 1 | |
j = 0 | |
} else { | |
// expand | |
i = i + 1 | |
j = j + 1 | |
} | |
} else { | |
if j > 0 { | |
// slide p in t | |
j = f[j-1] | |
} else { | |
i = i + 1 | |
} | |
} | |
} | |
} | |
func main() { | |
KMPMatch("abcdcbabcaabccdcbabcaabc", "abcaabc") | |
// a b c d c b a | |
// 0 0 0 1 1 2 3 | |
// match 6 | |
// match 17 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment