-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path00_kmp.py
38 lines (32 loc) · 1.05 KB
/
00_kmp.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
from typing import List
# dfa[j]: search[j+1] != text[i+1] 이면, text[i+1]을 dfa[j]에 들어있는 search의 index와 비교를 해야 함
def kmp(text: str, search: str) -> List[int]: # return all indices
# initialize dfa machine
i, j = 1, 0
dfa = [0]
while i < len(search):
# QUESTION: does this part gurantee O(1)?
while j>0 and search[i] != search[j]:
j = dfa[j-1]
# QUESTION: why?
if search[i] == search[j]:
j += 1
dfa.append(j)
i += 1
# do search
j, indices = 0, []
for i, c in enumerate(text):
# QUESTION: does this part gurantee O(1)?
while j>0 and c != search[j]:
j = dfa[j-1]
if c == search[j]:
if j+1 == len(search):
indices.append(i-len(search)+1)
# QUESTION: what happen after doing j = dfa[j]?
# 이미 indices에 추가 되었으므로, 그 부분을 한 번 틀렸다고 가정하고, j를 갱신해줌
j = dfa[j]
else:
j += 1
return indices
print(kmp("abxabcabcaby", "abcaby")) # [6]
print(kmp("abxabcabcaby", "bcab")) # [4, 7]