Skip to content

Commit 74a2553

Browse files
committed
kmp in python
1 parent 17bbd62 commit 74a2553

File tree

1 file changed

+45
-0
lines changed

1 file changed

+45
-0
lines changed

python/34_kmp/kmp.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
"""
2+
KMP algorithm
3+
4+
Author: Wenru Dong
5+
"""
6+
7+
from typing import List
8+
9+
def kmp(s: int, pattern: int) -> int:
10+
m = len(pattern)
11+
partial_match_table = _get_partial_match_table(pattern)
12+
j = 0
13+
for i in range(len(s)):
14+
while j and s[i] != pattern[j]:
15+
j = partial_match_table[j - 1] + 1
16+
j += 1
17+
if j == m:
18+
return i - m + 1
19+
return -1
20+
21+
22+
def _get_partial_match_table(pattern: int) -> List[int]:
23+
# Denote pi^k(i) as pi applied to i for k times,
24+
# i.e., pi^2(i) = pi(pi(i)).
25+
# Then we have the result:
26+
# pi(i) = pi^k(i-1) + 1,
27+
# where k is the smallest integer such that
28+
# pattern[pi^k(i-1)+1] == pattern[i].
29+
30+
m = len(pattern)
31+
pi = [0] * m
32+
pi[0] = k = -1 # We use k here to represent pi^k(i)
33+
for i in range(1, m):
34+
while k >= 0 and pattern[k + 1] != pattern[i]:
35+
k = pi[k]
36+
k += 1
37+
pi[i] = k
38+
return pi
39+
40+
41+
if __name__ == "__main__":
42+
43+
s = "abc abcdab abcdabcdabde"
44+
pattern = "bcdabd"
45+
print(kmp(s, pattern), s.find(pattern))

0 commit comments

Comments
 (0)