-
Notifications
You must be signed in to change notification settings - Fork 0
/
autocomplete using Trie.py
81 lines (68 loc) · 3.01 KB
/
autocomplete using 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
# autocomplete using Trie
import collections
class TrieNode:
def __init__(self) -> None:
self.endOfWord = True
self.children = collections.defaultdict(TrieNode)
# store the function name that are part of this node
self.childFunctions = set()
def __repr__(self) -> str:
return str(self.childFunctions)
class Trie:
def __init__(self) -> None:
self.root = TrieNode()
def insert(self, word):
current = self.root
for w in word:
current = current.children[w]
current.childFunctions.add(word)
current.endOfWord = True
class FunctionManager:
def __init__(self) -> None:
self.trie = Trie()
def addFunction(self, functionName):
self.trie.insert(functionName)
def printNode(self, node, char=None):
print(char, node)
for key, child in node.children.items():
self.printNode(child, key)
def getMatches(self, input):
result = []
def recur(node: TrieNode, input, index):
if index >= len(input):
# reached the end of input and can return the function names part of this node
result.extend(list(node.childFunctions))
return
# if first char or small case char and not in node.children, return
if (index == 0 or input[index].islower()) and input[index] not in node.children:
return
# first char or lower char should always have a node value
if index == 0 or input[index].islower():
return recur(node.children[input[index]], input, index+1)
else:
# for index>1 and capital character, we can traverse all small case nodes to check all functionName to find occurrance of capital char
for key, value in node.children.items():
if input[index] in value.children:
# if char is present, call on it's child nodes
recur(value.children[input[index]], input, index+1)
else:
# else call on all child nodes and backtrack
recur(value, input, index)
return
recur(self.trie.root, input, 0)
return result
fm = FunctionManager()
fm.addFunction('Container')
fm.addFunction('Panel')
fm.addFunction('AutoPanel')
fm.addFunction('RidePrinter')
fm.addFunction('ResumePanel')
fm.addFunction('RegularContainer')
fm.addFunction('RegularContainerBall')
# fm.printNode(fm.trie.root)
print(fm.getMatches("R")) # ["RegularContainerBall","ResumePanel", "RidePrinter", 'RegularContainer']
print(fm.getMatches("Re")) # ['RegularContainerBall', "ResumePanel", "RegularContainer"]
print(fm.getMatches("RP")) # ["RidePrinter", "ResumePanel"]
print(fm.getMatches("RPr")) # ["RidePrinter"]
print(fm.getMatches("RCB")) # ["RegularContainerBall"]
print(fm.getMatches("RCoBa")) # ["RegularContainerBall"]