@@ -29,6 +29,8 @@ def find(text, query, algorithm, **kwargs):
29
29
'kmp' -> Knuth-Morris-Pratt as given in [1].
30
30
31
31
'rabin_karp' -> Rabin–Karp algorithm as given in [2].
32
+
33
+ 'boyer_moore' -> Boyer-Moore algorithm as given in [3].
32
34
backend: pydatastructs.Backend
33
35
The backend to be used.
34
36
Optional, by default, the best available
@@ -64,6 +66,7 @@ def find(text, query, algorithm, **kwargs):
64
66
65
67
.. [1] https://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm
66
68
.. [2] https://en.wikipedia.org/wiki/Rabin%E2%80%93Karp_algorithm
69
+ .. [3] https://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_string-search_algorithm
67
70
"""
68
71
raise_if_backend_is_not_python (
69
72
find , kwargs .get ('backend' , Backend .PYTHON ))
@@ -158,3 +161,38 @@ def _rabin_karp(text, query):
158
161
positions .append (i )
159
162
160
163
return positions
164
+
165
+ def _boyer_moore (text , query ):
166
+ positions = DynamicOneDimensionalArray (int , 0 )
167
+ text_length , query_length = len (text ), len (query )
168
+
169
+ if text_length == 0 or query_length == 0 :
170
+ return positions
171
+
172
+ # Preprocessing Step
173
+ bad_match_table = dict ()
174
+ for i in range (query_length ):
175
+ bad_match_table [query [i ]] = i
176
+
177
+ shift = 0
178
+ # Matching procedure
179
+ while shift <= text_length - query_length :
180
+ j = query_length - 1
181
+ while j >= 0 and query [j ] == text [shift + j ]:
182
+ j -= 1
183
+ if j < 0 :
184
+ positions .append (shift )
185
+ if shift + query_length < text_length :
186
+ if text [shift + query_length ] in bad_match_table :
187
+ shift += query_length - bad_match_table [text [shift + query_length ]]
188
+ else :
189
+ shift += query_length + 1
190
+ else :
191
+ shift += 1
192
+ else :
193
+ letter_pos = text [shift + j ]
194
+ if letter_pos in bad_match_table :
195
+ shift += max (1 , j - bad_match_table [letter_pos ])
196
+ else :
197
+ shift += max (1 , j + 1 )
198
+ return positions
0 commit comments