-
Notifications
You must be signed in to change notification settings - Fork 58
/
Copy pathp17_17.py
77 lines (54 loc) · 1.84 KB
/
p17_17.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
67
68
69
70
71
72
73
74
75
76
77
from collections import defaultdict
from typing import List
# Method: Create a suffix tree, lookup each word against it
# Time: O(b^2 + w * b)
# Space: O(b^2)
# Note: w = words
def find_in_string(bigstr: str, words: List[str]):
sufix_trie = create_suffix_trie(bigstr)
res_dict = {}
for word in words:
pozs = find_starts(sufix_trie, word)
res_dict[word] = pozs
return res_dict
def find_starts(trie: dict, word: str) -> List[int]:
trie_pointer = trie
for c in word:
if c not in trie_pointer:
return []
else:
trie_pointer = trie_pointer[c]
return [end_index - len(word) + 1 for end_index in trie_pointer["index"]]
def build_trie_from_words(words: List[str]) -> dict:
word_trie = trie()
for word in words:
add_word_to_trie(word)
return word_trie
def trie():
return defaultdict(trie)
def create_suffix_trie(word):
sufs_trie = trie()
suffix_now = word
start_index = 0
while suffix_now:
add_word_to_trie(sufs_trie, suffix_now, start_index)
suffix_now = suffix_now[1:]
start_index += 1
return sufs_trie
def add_word_to_trie(trie: dict, word: str, start_index=0) -> None:
current_pointer = trie
index_of_chr = start_index
for char in word:
current_pointer = current_pointer[char]
if "index" in current_pointer:
current_pointer["index"].append(index_of_chr)
else:
current_pointer["index"] = [index_of_chr]
index_of_chr += 1
current_pointer["end"] = True
if __name__ == "__main__":
exs = [("mississippi", ["i", "iss", "ppi", "miss", "issi", "ipi"])]
for bigword, targets in exs:
print(f"{[x for x in range(len(bigword))]}")
print(" " + ", ".join(bigword))
print(f"Found targets at {find_in_string(bigword, targets)}")