status-go/vendor/github.com/yeqown/go-qrcode/v2/kmp_variant.go

60 lines
950 B
Go
Raw Normal View History

package qrcode
// kmp is variant of kmp algorithm to count the pattern been in
// src slice.
// DONE(@yeqown): implement this in generic way.
func kmp[v comparable](src, pattern []v, next []int) (count int) {
if next == nil {
next = kmpGetNext(pattern)
}
slen := len(src)
plen := len(pattern)
i := 0 // cursor of src
j := 0 // cursor of pattern
loop:
for i < slen && j < plen {
if j == -1 || src[i] == pattern[j] {
i++
j++
} else {
j = next[j]
}
}
if j == plen {
if i-j >= 0 {
count++
}
// reset cursor to count duplicate pattern.
// such as: "aaaa" and "aa", we want 3 rather than 2.
i -= plen - 1
j = 0
goto loop
}
return count
}
func kmpGetNext[v comparable](pattern []v) []int {
fail := make([]int, len(pattern))
fail[0] = -1
j := 0
k := -1
for j < len(pattern)-1 {
if k == -1 || pattern[j] == pattern[k] {
k++
j++
fail[j] = k
} else {
k = fail[k]
}
}
return fail
}