-
Notifications
You must be signed in to change notification settings - Fork 0
/
trie.py
58 lines (44 loc) · 1.57 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
import json
class TrieNode:
def __init__(self, data=None, parent=None):
self.children = {}
self.data = data
self.parent = parent
def into_json(self):
return json.dumps(self.into_obj())
def into_obj(self):
return [self.data, {char: node.into_obj() for char, node in self.children.items()}]
class Trie:
def __init__(self):
self.root = TrieNode(parent=None)
self._len = 0
def into_json(self):
return self.root.into_json()
def insert(self, string, data):
self._len += 1
node = self.root
for char in string:
node = node.children.setdefault(char, TrieNode(parent=node))
node.data = data
def prefix_search(self, prefix):
node = self._find_exact_node(prefix)
if node.data is not None:
yield prefix, node.data
yield from self._prefix_search_from_node(node, prefix)
def _prefix_search_from_node(self, node, current_string):
for char, child_node in node.children.items():
new_string = current_string + char
if child_node.data:
yield new_string, child_node.data
yield from self._prefix_search_from_node(child_node, new_string)
def _find_exact_node(self, key):
node = self.root
for char in key:
node = node.children.get(char)
if node is None:
return None
return node
def find_exact(self, search):
return self._find_exact_node(search).data
def __len__(self):
return self._len