mirror of
https://github.com/golang/go
synced 2024-11-22 20:24:47 -07:00
bytes,internal/bytealg: eliminate IndexRabinKarpBytes using generics
This is a follow-up to CL 538175.
Change-Id: Iec2523b36a16d7e157c17858c89fcd43c2470d58
GitHub-Last-Rev: 812d36e57c
GitHub-Pull-Request: golang/go#63770
Reviewed-on: https://go-review.googlesource.com/c/go/+/538195
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
Auto-Submit: Keith Randall <khr@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
This commit is contained in:
parent
cbc403af1d
commit
68e52bc03c
@ -1331,7 +1331,7 @@ func Index(s, sep []byte) int {
|
|||||||
// we should cutover at even larger average skips,
|
// we should cutover at even larger average skips,
|
||||||
// because Equal becomes that much more expensive.
|
// because Equal becomes that much more expensive.
|
||||||
// This code does not take that effect into account.
|
// This code does not take that effect into account.
|
||||||
j := bytealg.IndexRabinKarpBytes(s[i:], sep)
|
j := bytealg.IndexRabinKarp(s[i:], sep)
|
||||||
if j < 0 {
|
if j < 0 {
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
@ -24,10 +24,6 @@ const (
|
|||||||
// If MaxLen is not 0, make sure MaxLen >= 4.
|
// If MaxLen is not 0, make sure MaxLen >= 4.
|
||||||
var MaxLen int
|
var MaxLen int
|
||||||
|
|
||||||
// FIXME: the logic of IndexRabinKarpBytes and IndexRabinKarp are exactly the same,
|
|
||||||
// except that the types are different.
|
|
||||||
// Can we eliminate one of them without causing allocation?
|
|
||||||
|
|
||||||
// PrimeRK is the prime base used in Rabin-Karp algorithm.
|
// PrimeRK is the prime base used in Rabin-Karp algorithm.
|
||||||
const PrimeRK = 16777619
|
const PrimeRK = 16777619
|
||||||
|
|
||||||
@ -65,34 +61,9 @@ func HashStrRev[T string | []byte](sep T) (uint32, uint32) {
|
|||||||
return hash, pow
|
return hash, pow
|
||||||
}
|
}
|
||||||
|
|
||||||
// IndexRabinKarpBytes uses the Rabin-Karp search algorithm to return the index of the
|
|
||||||
// first occurrence of substr in s, or -1 if not present.
|
|
||||||
func IndexRabinKarpBytes(s, sep []byte) int {
|
|
||||||
// Rabin-Karp search
|
|
||||||
hashsep, pow := HashStr(sep)
|
|
||||||
n := len(sep)
|
|
||||||
var h uint32
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
h = h*PrimeRK + uint32(s[i])
|
|
||||||
}
|
|
||||||
if h == hashsep && Equal(s[:n], sep) {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
for i := n; i < len(s); {
|
|
||||||
h *= PrimeRK
|
|
||||||
h += uint32(s[i])
|
|
||||||
h -= pow * uint32(s[i-n])
|
|
||||||
i++
|
|
||||||
if h == hashsep && Equal(s[i-n:i], sep) {
|
|
||||||
return i - n
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
|
|
||||||
// IndexRabinKarp uses the Rabin-Karp search algorithm to return the index of the
|
// IndexRabinKarp uses the Rabin-Karp search algorithm to return the index of the
|
||||||
// first occurrence of substr in s, or -1 if not present.
|
// first occurrence of substr in s, or -1 if not present.
|
||||||
func IndexRabinKarp(s, substr string) int {
|
func IndexRabinKarp[T string | []byte](s, substr T) int {
|
||||||
// Rabin-Karp search
|
// Rabin-Karp search
|
||||||
hashss, pow := HashStr(substr)
|
hashss, pow := HashStr(substr)
|
||||||
n := len(substr)
|
n := len(substr)
|
||||||
@ -100,7 +71,7 @@ func IndexRabinKarp(s, substr string) int {
|
|||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
h = h*PrimeRK + uint32(s[i])
|
h = h*PrimeRK + uint32(s[i])
|
||||||
}
|
}
|
||||||
if h == hashss && s[:n] == substr {
|
if h == hashss && string(s[:n]) == string(substr) {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
for i := n; i < len(s); {
|
for i := n; i < len(s); {
|
||||||
@ -108,7 +79,7 @@ func IndexRabinKarp(s, substr string) int {
|
|||||||
h += uint32(s[i])
|
h += uint32(s[i])
|
||||||
h -= pow * uint32(s[i-n])
|
h -= pow * uint32(s[i-n])
|
||||||
i++
|
i++
|
||||||
if h == hashss && s[i-n:i] == substr {
|
if h == hashss && string(s[i-n:i]) == string(substr) {
|
||||||
return i - n
|
return i - n
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user