@@ -124,3 +124,130 @@ func IndexString(str, sub string) int {
124124 }
125125 return - 1
126126}
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