-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathc-13.21.py
66 lines (57 loc) · 1.31 KB
/
c-13.21.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
"""
Redo Exercise C-13.19, adapting the Knuth-Morris-Pratt pattern-matching
algorithm appropriately to implement a function count kmp(T,P).
"""
def find_kmp(T, P, start=0):
n, m = len(T), len(P)
if m == 0 or start > n - m: return -1
fail = compute_kmp_fail(P)
j = 0 + start
k = 0
while j < n:
if T[j] == P[k]:
if k == m - 1:
return j - m + 1
j += 1
k += 1
elif k > 0:
k = fail[k-1]
else:
j += 1
return -1
def compute_kmp_fail(P):
m = len(P)
fail = [0] * m
j = 1
k = 0
while j < m:
if P[j] == P[k]:
fail[j] = k + 1
j += 1
k += 1
elif k > 0:
k = fail[k-1]
else:
j += 1
return fail
def count_kmp(T, P):
n, m = len(T), len(P)
if m == 0: return n + 1
k = 0
cnt = 0
while True:
j = find_kmp(T, P, start=k)
if j == -1:
break
else:
cnt += 1
k = j + m
return cnt
if __name__ == "__main__":
T = 'test to last'
P = 'st'
assert count_kmp(T, P) == T.count(P)
assert find_kmp(T, P, start=len(T)-1) == -1 # len(T) - start < len(P) - can't be there
T = 'test'
P = ''
assert count_kmp(T, P) == T.count(P)