case n > len(s):
return -1
}
- // Rabin-Karp search from the end of the string
- hashss, pow := bytealg.HashStrRev(sep)
- last := len(s) - n
- var h uint32
- for i := len(s) - 1; i >= last; i-- {
- h = h*bytealg.PrimeRK + uint32(s[i])
- }
- if h == hashss && Equal(s[last:], sep) {
- return last
- }
- for i := last - 1; i >= 0; i-- {
- h *= bytealg.PrimeRK
- h += uint32(s[i])
- h -= pow * uint32(s[i+n])
- if h == hashss && Equal(s[i:i+n], sep) {
- return i
- }
- }
- return -1
+ return bytealg.LastIndexRabinKarp(s, sep)
}
// LastIndexByte returns the index of the last instance of c in s, or -1 if c is not present in s.
}
// IndexRabinKarp uses the Rabin-Karp search algorithm to return the index of the
-// first occurrence of substr in s, or -1 if not present.
-func IndexRabinKarp[T string | []byte](s, substr T) int {
+// first occurrence of sep in s, or -1 if not present.
+func IndexRabinKarp[T string | []byte](s, sep T) int {
// Rabin-Karp search
- hashss, pow := HashStr(substr)
- n := len(substr)
+ hashss, pow := HashStr(sep)
+ n := len(sep)
var h uint32
for i := 0; i < n; i++ {
h = h*PrimeRK + uint32(s[i])
}
- if h == hashss && string(s[:n]) == string(substr) {
+ if h == hashss && string(s[:n]) == string(sep) {
return 0
}
for i := n; i < len(s); {
h += uint32(s[i])
h -= pow * uint32(s[i-n])
i++
- if h == hashss && string(s[i-n:i]) == string(substr) {
+ if h == hashss && string(s[i-n:i]) == string(sep) {
return i - n
}
}
return -1
}
+// LastIndexRabinKarp uses the Rabin-Karp search algorithm to return the last index of the
+// occurrence of sep in s, or -1 if not present.
+func LastIndexRabinKarp[T string | []byte](s, sep T) int {
+ // Rabin-Karp search from the end of the string
+ hashss, pow := HashStrRev(sep)
+ n := len(sep)
+ last := len(s) - n
+ var h uint32
+ for i := len(s) - 1; i >= last; i-- {
+ h = h*PrimeRK + uint32(s[i])
+ }
+ if h == hashss && string(s[last:]) == string(sep) {
+ return last
+ }
+ for i := last - 1; i >= 0; i-- {
+ h *= PrimeRK
+ h += uint32(s[i])
+ h -= pow * uint32(s[i+n])
+ if h == hashss && string(s[i:i+n]) == string(sep) {
+ return i
+ }
+ }
+ return -1
+}
+
// MakeNoZero makes a slice of length and capacity n without zeroing the bytes.
// It is the caller's responsibility to ensure uninitialized bytes
// do not leak to the end user.