-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTrie.py
233 lines (199 loc) · 6.98 KB
/
Trie.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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
class Trie():
def __init__(self):
"""
Create a trie object. This is implemented as a dictionary where keys are
consisted as letters and values are dictionaries that relate to letters
following the key in words.
Parameters
----------
trie : dict of str: dict
maxDepth : int
Methods
----------
setMaxDepth(value) - Set the max depth for searching.
buildTrie(words) - Builds a trie using an array of words.
getTrie() - Returns the trie object. (Reference to the root)
insertWord(word) - Allows insertion of a word to the trie.
deleteWord(word) - Allows deletion of a word to the trie.
getDirectChildren(word) - Returns array of letters that follow the given
word in the trie.
containsWord(word) - Returns boolean regarding if that word is in the trie or not.
findCandidates(word) - Returns array of all possible words proceeding the given
text.
"""
self.trie = {}
self.maxDepth = -1
def setMaxDepth(self,value):
"""
This function set the maxDepth to search the trie for candidate words.
Parameters
------------
value : int
Value to set the maxDepth to
Return
------------
None
"""
if isinstance(value,int):
self.maxDepth = value
def buildTrie(self,words):
"""
Builds a trie using the words provided.
Parameters
----------
words : Array of strings to be added to the trie.
Return
----------
None
"""
for word in words:
self.insertWord(word)
def getTrie(self):
"""
This function will return the root of the trie.
Returns
----------
dict - Dictionary pointing to the root of the trie.
"""
return self.trie
def insertWord(self,word):
"""
Function to insert a word into the trie. Words are converted to lowercase
before being added to the trie.
Parameters
----------
word : str
This is the word that will be added to the trie.
Returns
----------
None
"""
#Create a new object that can be manipulated to insert a new word.
trie = self.trie
for char in word.lower():
if trie.get(char,False) == False:
trie[char] = {}
trie=trie[char]
trie["!"] = True
def deleteWord(self,word):
"""
This function will remove any word currently in the trie.
Parameters
----------
word : str
This is the word that will be removed from the trie.
Returns
----------
boolean - True if the word has been removed and false if it hasn't.
"""
trie = self.trie
if self.containsWord(word):
for char in word.lower():
trie=trie[char]
trie.pop("!")
return True
else:
return False
def getDirectChildren(self,word):
"""
This function will return an array of letters, if any, of the next letters in the trie after the given word.
Parameters
----------
word : str
This is the word that will be used to find the next proceeding letters.
Returns
----------
list - List of letters.
"""
trie = self.trie
for char in word.lower():
if trie.get(char,False) is not False:
trie=trie[char]
else:
return "Error: Word is not currently implemented!"
return list(trie.keys())
def getChildren(self,trie):
"""
This is used to return the dictionaries of the children of the trie given.
Parameters
----------
trie : dict
This is the trie that the children will be found from.
Returns
----------
list - List of dictionaries.
"""
return list(trie.keys())
def containsWord(self,word):
"""
This is used to find if a word is present in the trie or not.
Parameters
----------
word : str
This is the word that is being checked for in the trie.
Returns
----------
boolean - True or False (if it's in the trie or not).
"""
trie = self.trie
for char in word.lower():
if trie.get(char,False) == False:
return False
trie=trie[char]
if trie.get("!",False) == False:
return False
else:
return True
def findCandidates(self,word,candidateWords,maxDepth):
"""
Function to find the candidate words proceeding the word.
This function uses recursion and updates a private variable.
Parameters
----------
word : str
This is the word that is being used to look for complete words.
candidateWords : list
This is a list of words that the given word is a prefix of.
maxDepth : int
This is the maximum amount of charaters extra that a word can be found. (e.g J,[],2 -> Jam but not Jame)
Returns
----------
list - This is a list of words that the given word is a prefix of.
"""
#Navigate to end of given word
trie = self.trie
md = maxDepth
for char in word.lower():
if trie.get(char,False) == False:
return []
trie=trie[char]
#Naviagte through the children until finding a "!"
children = self.getChildren(trie)
if "!" in children:
candidateWords.append(word)
for letter in children:
if letter!="!" and (md != 0):
self.findCandidates(word+letter,candidateWords,md-1)
return candidateWords
def manualTesting():
help(Trie)
print(main.trie)
print(main.getTrie)
print(main.insertWord("Jake"))
print(main.insertWord("James"))
print(main.insertWord("Jam"))
print(main.trie)
print(*main.trie["j"]["a"])
print(main.getDirectChildren("Ja"))
testWord = "James"
print(f'Is word "{testWord}" in the trie? {"Yes" if main.containsWord(testWord) else "No"}')
main.setMaxDepth(3)
print(main.maxDepth)
print(main.findCandidates("j",[],main.maxDepth))
print("Remove jam")
main.deleteWord("jam")
print(main.findCandidates("j",[],main.maxDepth))
print(main.getChildren(main.trie["j"]["a"]["m"]))
if __name__ == "__main__":
main = Trie()
manualTesting()