From 3cc9859c9c9039d3ce621d4fd750398dc6b54893 Mon Sep 17 00:00:00 2001 From: Wenru Dong Date: Mon, 10 Dec 2018 21:02:51 +0000 Subject: [PATCH] fix bugs --- python/34_kmp/kmp.py | 43 ++++++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/python/34_kmp/kmp.py b/python/34_kmp/kmp.py index 22f11599..1e00a7c3 100644 --- a/python/34_kmp/kmp.py +++ b/python/34_kmp/kmp.py @@ -9,10 +9,11 @@ def kmp(s: int, pattern: int) -> int: m = len(pattern) partial_match_table = _get_partial_match_table(pattern) + print(partial_match_table) j = 0 for i in range(len(s)): - while j and s[i] != pattern[j]: - j = partial_match_table[j - 1] + 1 + while j >= 0 and s[i] != pattern[j]: + j = partial_match_table[j] j += 1 if j == m: return i - m + 1 @@ -20,26 +21,42 @@ def kmp(s: int, pattern: int) -> int: 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)). + # Denote πᵏ(i) as π applied to i for k times, + # i.e., π²(i) = π(π(i)). # Then we have the result: - # pi(i) = pi^k(i-1) + 1, + # π(i) = πᵏ(i-1) + 1, # where k is the smallest integer such that - # pattern[pi^k(i-1)+1] == pattern[i]. + # pattern[πᵏ(i-1)+1] == pattern[i]. + + # The value of π means the maximum length + # of proper prefix/suffix. + # The index of π means the length of the prefix + # considered for pattern. + # For example, π[2] means we are considering the first 2 characters + # of the pattern. + # If π[2] == 1, it means for the prefix of the pattern, P[0]P[1], + # it has a maximum length proper prefix of 1, which is also the + # suffix of P[0]P[1]. + # We also add a π[0] == -1 for easier handling of boundary + # condition. 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] + π = [0] * (m + 1) + π[0] = k = -1 # We use k here to represent πᵏ(i) + for i in range(1, m + 1): + while k >= 0 and pattern[k] != pattern[i - 1]: + k = π[k] k += 1 - pi[i] = k - return pi + π[i] = k + return π if __name__ == "__main__": s = "abc abcdab abcdabcdabde" pattern = "bcdabd" + print(kmp(s, pattern), s.find(pattern)) + + s = "hello" + pattern = "ll" print(kmp(s, pattern), s.find(pattern)) \ No newline at end of file