@@ -124,3 +124,130 @@ func IndexString(str, sub string) int {
124
124
}
125
125
return - 1
126
126
}
127
+
128
+ // Copyright 2020 The Go Authors. All rights reserved.
129
+ // Use of this source code is governed by a BSD-style
130
+ // license that can be found in the LICENSE file.
131
+
132
+ // The following code has been copied from the Go 1.15 release tree.
133
+
134
+ // PrimeRK is the prime base used in Rabin-Karp algorithm.
135
+ const PrimeRK = 16777619
136
+
137
+ // HashStrBytes returns the hash and the appropriate multiplicative
138
+ // factor for use in Rabin-Karp algorithm.
139
+ func HashStrBytes (sep []byte ) (uint32 , uint32 ) {
140
+ hash := uint32 (0 )
141
+ for i := 0 ; i < len (sep ); i ++ {
142
+ hash = hash * PrimeRK + uint32 (sep [i ])
143
+ }
144
+ var pow , sq uint32 = 1 , PrimeRK
145
+ for i := len (sep ); i > 0 ; i >>= 1 {
146
+ if i & 1 != 0 {
147
+ pow *= sq
148
+ }
149
+ sq *= sq
150
+ }
151
+ return hash , pow
152
+ }
153
+
154
+ // HashStr returns the hash and the appropriate multiplicative
155
+ // factor for use in Rabin-Karp algorithm.
156
+ func HashStr (sep string ) (uint32 , uint32 ) {
157
+ hash := uint32 (0 )
158
+ for i := 0 ; i < len (sep ); i ++ {
159
+ hash = hash * PrimeRK + uint32 (sep [i ])
160
+ }
161
+ var pow , sq uint32 = 1 , PrimeRK
162
+ for i := len (sep ); i > 0 ; i >>= 1 {
163
+ if i & 1 != 0 {
164
+ pow *= sq
165
+ }
166
+ sq *= sq
167
+ }
168
+ return hash , pow
169
+ }
170
+
171
+ // HashStrRevBytes returns the hash of the reverse of sep and the
172
+ // appropriate multiplicative factor for use in Rabin-Karp algorithm.
173
+ func HashStrRevBytes (sep []byte ) (uint32 , uint32 ) {
174
+ hash := uint32 (0 )
175
+ for i := len (sep ) - 1 ; i >= 0 ; i -- {
176
+ hash = hash * PrimeRK + uint32 (sep [i ])
177
+ }
178
+ var pow , sq uint32 = 1 , PrimeRK
179
+ for i := len (sep ); i > 0 ; i >>= 1 {
180
+ if i & 1 != 0 {
181
+ pow *= sq
182
+ }
183
+ sq *= sq
184
+ }
185
+ return hash , pow
186
+ }
187
+
188
+ // HashStrRev returns the hash of the reverse of sep and the
189
+ // appropriate multiplicative factor for use in Rabin-Karp algorithm.
190
+ func HashStrRev (sep string ) (uint32 , uint32 ) {
191
+ hash := uint32 (0 )
192
+ for i := len (sep ) - 1 ; i >= 0 ; i -- {
193
+ hash = hash * PrimeRK + uint32 (sep [i ])
194
+ }
195
+ var pow , sq uint32 = 1 , PrimeRK
196
+ for i := len (sep ); i > 0 ; i >>= 1 {
197
+ if i & 1 != 0 {
198
+ pow *= sq
199
+ }
200
+ sq *= sq
201
+ }
202
+ return hash , pow
203
+ }
204
+
205
+ // IndexRabinKarpBytes uses the Rabin-Karp search algorithm to return the index of the
206
+ // first occurence of substr in s, or -1 if not present.
207
+ func IndexRabinKarpBytes (s , sep []byte ) int {
208
+ // Rabin-Karp search
209
+ hashsep , pow := HashStrBytes (sep )
210
+ n := len (sep )
211
+ var h uint32
212
+ for i := 0 ; i < n ; i ++ {
213
+ h = h * PrimeRK + uint32 (s [i ])
214
+ }
215
+ if h == hashsep && Equal (s [:n ], sep ) {
216
+ return 0
217
+ }
218
+ for i := n ; i < len (s ); {
219
+ h *= PrimeRK
220
+ h += uint32 (s [i ])
221
+ h -= pow * uint32 (s [i - n ])
222
+ i ++
223
+ if h == hashsep && Equal (s [i - n :i ], sep ) {
224
+ return i - n
225
+ }
226
+ }
227
+ return - 1
228
+ }
229
+
230
+ // IndexRabinKarp uses the Rabin-Karp search algorithm to return the index of the
231
+ // first occurence of substr in s, or -1 if not present.
232
+ func IndexRabinKarp (s , substr string ) int {
233
+ // Rabin-Karp search
234
+ hashss , pow := HashStr (substr )
235
+ n := len (substr )
236
+ var h uint32
237
+ for i := 0 ; i < n ; i ++ {
238
+ h = h * PrimeRK + uint32 (s [i ])
239
+ }
240
+ if h == hashss && s [:n ] == substr {
241
+ return 0
242
+ }
243
+ for i := n ; i < len (s ); {
244
+ h *= PrimeRK
245
+ h += uint32 (s [i ])
246
+ h -= pow * uint32 (s [i - n ])
247
+ i ++
248
+ if h == hashss && s [i - n :i ] == substr {
249
+ return i - n
250
+ }
251
+ }
252
+ return - 1
253
+ }
0 commit comments