@@ -49,7 +49,10 @@ class Trie(object):
49
49
@classmethod
50
50
def methods (cls ):
51
51
return ['__new__' , 'insert' , 'is_present' , 'delete' ,
52
- 'strings_with_prefix' ]
52
+ 'strings_with_prefix' , 'count_words' , 'longest_common_prefix' ,
53
+ 'autocomplete' , 'bulk_insert' , 'clear' , 'is_empty' ,
54
+ 'all_words' , 'shortest_unique_prefix' , 'starts_with' ,
55
+ 'longest_word' ]
53
56
54
57
def __new__ (cls , ** kwargs ):
55
58
raise_if_backend_is_not_python (
@@ -176,26 +179,191 @@ def strings_with_prefix(self, string: str) -> list:
176
179
The list of strings with the given prefix.
177
180
"""
178
181
179
- def _collect (prefix : str , node : TrieNode , strings : list ) -> str :
180
- TrieNode_stack = Stack ()
181
- TrieNode_stack .append ((node , prefix ))
182
- while TrieNode_stack :
183
- walk , curr_prefix = TrieNode_stack .pop ()
184
- if walk .is_terminal :
185
- strings .append (curr_prefix + walk .char )
186
- for child in walk ._children :
187
- TrieNode_stack .append ((walk .get_child (child ), curr_prefix + walk .char ))
182
+ def _collect (node : TrieNode , prefix : str , strings : list ):
183
+ if node .is_terminal :
184
+ strings .append (prefix )
185
+ for child in node ._children :
186
+ _collect (node .get_child (child ), prefix + child , strings )
188
187
189
188
strings = []
190
- prefix = ""
191
189
walk = self .root
192
190
for char in string :
193
- walk = walk .get_child (char )
194
- if walk is None :
191
+ if walk .get_child (char ) is None :
195
192
return strings
196
- prefix += char
197
- if walk .is_terminal :
198
- strings .append (walk .char )
199
- for child in walk ._children :
200
- _collect (prefix , walk .get_child (child ), strings )
193
+ walk = walk .get_child (char )
194
+ _collect (walk , string , strings )
201
195
return strings
196
+
197
+ def count_words (self ) -> int :
198
+ """
199
+ Returns the total number of words inserted into the trie.
200
+
201
+ Returns
202
+ =======
203
+
204
+ count: int
205
+ The total number of words in the trie.
206
+ """
207
+ def _count (node : TrieNode ) -> int :
208
+ count = 0
209
+ if node .is_terminal :
210
+ count += 1
211
+ for child in node ._children :
212
+ count += _count (node .get_child (child ))
213
+ return count
214
+
215
+ return _count (self .root )
216
+
217
+ def longest_common_prefix (self ) -> str :
218
+ """
219
+ Finds the longest common prefix among all the words in the trie.
220
+
221
+ Returns
222
+ =======
223
+
224
+ prefix: str
225
+ The longest common prefix.
226
+ """
227
+ prefix = ""
228
+ walk = self .root
229
+ while len (walk ._children ) == 1 and not walk .is_terminal :
230
+ char = next (iter (walk ._children ))
231
+ prefix += char
232
+ walk = walk .get_child (char )
233
+ return prefix
234
+
235
+ def autocomplete (self , prefix : str ) -> list :
236
+ """
237
+ Provides autocomplete suggestions based on the given prefix.
238
+
239
+ Parameters
240
+ ==========
241
+
242
+ prefix: str
243
+
244
+ Returns
245
+ =======
246
+
247
+ suggestions: list
248
+ A list of autocomplete suggestions.
249
+ """
250
+ return self .strings_with_prefix (prefix )
251
+
252
+ def bulk_insert (self , words : list ) -> None :
253
+ """
254
+ Inserts multiple words into the trie.
255
+
256
+ Parameters
257
+ ==========
258
+
259
+ words: list
260
+ A list of words to be inserted.
261
+
262
+ Returns
263
+ =======
264
+
265
+ None
266
+ """
267
+ for word in words :
268
+ self .insert (word )
269
+
270
+ def clear (self ) -> None :
271
+ """
272
+ Clears the trie, removing all words.
273
+
274
+ Returns
275
+ =======
276
+
277
+ None
278
+ """
279
+ self .root = TrieNode ()
280
+
281
+ def is_empty (self ) -> bool :
282
+ """
283
+ Checks if the trie is empty.
284
+
285
+ Returns
286
+ =======
287
+
288
+ bool
289
+ True if the trie is empty, False otherwise.
290
+ """
291
+ return not self .root ._children
292
+
293
+ def all_words (self ) -> list :
294
+ """
295
+ Retrieves all words stored in the trie.
296
+
297
+ Returns
298
+ =======
299
+
300
+ words: list
301
+ A list of all words in the trie.
302
+ """
303
+ return self .strings_with_prefix ("" )
304
+
305
+ def shortest_unique_prefix (self ) -> dict :
306
+ """
307
+ Finds the shortest unique prefix for each word in the trie.
308
+
309
+ Returns
310
+ =======
311
+ prefixes: dict
312
+ A dictionary where keys are words and values are their shortest unique prefixes.
313
+ """
314
+ def _find_prefix (node : TrieNode , prefix : str , prefixes : dict , word : str = "" ):
315
+ if node .is_terminal :
316
+ prefixes [word ] = prefix # Store full word as key
317
+ for child in node ._children :
318
+ new_word = word + child # Build full word
319
+ new_prefix = prefix + child
320
+ if len (node ._children ) > 1 or node .is_terminal :
321
+ _find_prefix (node .get_child (child ), new_prefix , prefixes , new_word )
322
+ else :
323
+ _find_prefix (node .get_child (child ), prefix , prefixes , new_word )
324
+
325
+ prefixes = {}
326
+ _find_prefix (self .root , "" , prefixes )
327
+ return prefixes
328
+
329
+
330
+ def starts_with (self , prefix : str ) -> bool :
331
+ """
332
+ Checks if any word in the trie starts with the given prefix.
333
+
334
+ Parameters
335
+ ==========
336
+
337
+ prefix: str
338
+
339
+ Returns
340
+ =======
341
+
342
+ bool
343
+ True if any word starts with the prefix, False otherwise.
344
+ """
345
+ walk = self .root
346
+ for char in prefix :
347
+ if walk .get_child (char ) is None :
348
+ return False
349
+ walk = walk .get_child (char )
350
+ return True
351
+
352
+ def longest_word (self ) -> str :
353
+ """
354
+ Finds the longest word stored in the trie.
355
+
356
+ Returns
357
+ =======
358
+
359
+ word: str
360
+ The longest word in the trie.
361
+ """
362
+ def _longest (node : TrieNode , current_word : str , longest_word : str ) -> str :
363
+ if node .is_terminal and len (current_word ) > len (longest_word ):
364
+ longest_word = current_word
365
+ for child in node ._children :
366
+ longest_word = _longest (node .get_child (child ), current_word + child , longest_word )
367
+ return longest_word
368
+
369
+ return _longest (self .root , "" , "" )
0 commit comments