Skip to content

Commit

Permalink
kmp in python
Browse files Browse the repository at this point in the history
  • Loading branch information
jerryderry committed Dec 9, 2018
1 parent 17bbd62 commit 74a2553
Showing 1 changed file with 45 additions and 0 deletions.
45 changes: 45 additions & 0 deletions python/34_kmp/kmp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
"""
KMP algorithm
Author: Wenru Dong
"""

from typing import List

def kmp(s: int, pattern: int) -> int:
m = len(pattern)
partial_match_table = _get_partial_match_table(pattern)
j = 0
for i in range(len(s)):
while j and s[i] != pattern[j]:
j = partial_match_table[j - 1] + 1
j += 1
if j == m:
return i - m + 1
return -1


def _get_partial_match_table(pattern: int) -> List[int]:
# Denote pi^k(i) as pi applied to i for k times,
# i.e., pi^2(i) = pi(pi(i)).
# Then we have the result:
# pi(i) = pi^k(i-1) + 1,
# where k is the smallest integer such that
# pattern[pi^k(i-1)+1] == pattern[i].

m = len(pattern)
pi = [0] * m
pi[0] = k = -1 # We use k here to represent pi^k(i)
for i in range(1, m):
while k >= 0 and pattern[k + 1] != pattern[i]:
k = pi[k]
k += 1
pi[i] = k
return pi


if __name__ == "__main__":

s = "abc abcdab abcdabcdabde"
pattern = "bcdabd"
print(kmp(s, pattern), s.find(pattern))

0 comments on commit 74a2553

Please sign in to comment.