Skip to content

Commit a5dc90c

Browse files
committed
kmp_search can now find *all* indices, not just the first one
1 parent 30fd54c commit a5dc90c

2 files changed

Lines changed: 11 additions & 9 deletions

File tree

algorithms/searching/kmp_search.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,28 +15,30 @@
1515
1616
Psuedo Code: CLRS. Introduction to Algorithms. 3rd ed.
1717
18-
kmp_search.search(sorted_list) -> integer
19-
kmp_search.search(sorted_list) -> False
18+
kmp_search.search(sorted_list) -> list[integers]
19+
kmp_search.search(sorted_list) -> list[empty]
2020
"""
2121

2222

2323
def search(string, word):
2424
word_length = len(word)
2525
prefix = compute_prefix(word)
26-
q = 0
26+
offsets = []
27+
q = 0 # q is the number of characters matched
2728
for i in xrange(len(string)):
2829
while q > 0 and word[q] != string[i]:
29-
q = prefix[q - 1]
30+
q = prefix[q - 1] # next character does not match
3031
if word[q] == string[i]:
31-
q = q + 1
32+
q += 1
3233
if q == word_length:
33-
return i - word_length + 1
34-
return False
34+
offsets.append(i - word_length + 1)
35+
q = prefix[q - 1] # look for next match
36+
return offsets
3537

3638

3739
def compute_prefix(word):
3840
word_length = len(word)
39-
prefix = [0] * word_length
41+
prefix = [0 for i in xrange(word_length)]
4042
k = 0
4143

4244
for q in xrange(1, word_length):

algorithms/tests/test_searching.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ def test_kmpsearch(self):
4141
self.string = "ABCDE FG ABCDEABCDEF"
4242
rv1 = kmp_search.search(self.string, "ABCDEA")
4343
rv2 = kmp_search.search(self.string, "ABCDER")
44-
self.assertIs(rv1, 9)
44+
self.assertIs(rv1[0], 9)
4545
self.assertFalse(rv2)
4646

4747

0 commit comments

Comments
 (0)