-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathQ17_multi_search.py
80 lines (66 loc) · 2.07 KB
/
Q17_multi_search.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
78
79
80
import unittest
class TrieNode:
def __init__(self):
self.children = {}
self.is_word = False
class Trie:
def __init__(self):
self.root = TrieNode()
def add_word(self, word):
node = self.root
for c in word:
if c not in node.children:
node.children[c] = TrieNode()
node = node.children[c]
node.is_word = True
def search_word(self, word):
node = self.root
for c in word:
if c not in node.children:
return False
node = node.children[c]
return node.is_word
def multi_search(string, words):
trie = Trie()
for word in words:
trie.add_word(word)
word_locations = {}
for i in range(len(string)):
node = trie.root
idx = i
while idx < len(string):
c = string[idx]
if c not in node.children:
break
node = node.children[c]
if node.is_word:
word = string[i : idx + 1]
if word in word_locations:
word_locations[word].append(i)
else:
word_locations[word] = [i]
idx += 1
return word_locations
class Test(unittest.TestCase):
def test_trie(self):
trie = Trie()
trie.add_word("test")
self.assertEqual(True, trie.search_word("test"))
self.assertEqual(False, trie.search_word("testing"))
def test_multi_search(self):
test_string = "dogwalk"
test_words = ["dog", "walk"]
expected = {"dog": [0], "walk": [3]}
self.assertEqual(expected, multi_search(test_string, test_words))
test_string = "iamateststringiamlong"
test_words = ["a", "i", "am", "test", "string", "long"]
expected = {
"i": [0, 11, 14],
"a": [1, 3, 15],
"am": [1, 15],
"test": [4],
"string": [8],
"long": [17],
}
result = multi_search(test_string, test_words)
self.assertEqual(expected, result)