TernarySearchTrie   A
last analyzed

Complexity

Total Complexity 32

Size/Duplication

Total Lines 106
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 106
rs 9.6
wmc 32

13 Methods

Rating   Name   Duplication   Size   Complexity  
A is_empty() 0 2 1
A put() 0 2 1
A contains_key() 0 5 2
B _get() 0 14 5
A delete() 0 2 1
A get() 0 5 2
A size() 0 2 1
B _delete() 0 16 5
A keys() 0 4 1
B _put() 0 17 6
A collect_values() 0 9 3
A values() 0 4 1
A collect() 0 8 3
1
class TstNode(object):
2
    key = None
3
    value = None
4
    mid = None
5
    left = None
6
    right = None
7
8
    def __init__(self, key=None, value=None, left=None, right=None, mid=None):
9
        if key is not None:
10
            self.key = key
11
        if value is not None:
12
            self.value = value
13
        if mid is not None:
14
            self.mid = mid
15
        if left is not None:
16
            self.left = left
17
        if right is not None:
18
            self.right = right
19
20
21
def char_at(s, index):
22
    if len(s) <= index:
23
        return -1
24
    return ord(s[index])
25
26
27
class TernarySearchTrie(object):
28
    root = None
29
    N = 0
30
31
    def put(self, key, value):
32
        self.root = self._put(self.root, key, value, 0)
33
34
    def _put(self, x, key, value, d):
35
        c = char_at(key, d)
36
        if x is None:
37
            x = TstNode(key=c, value=None)
38
        compared = c - x.key
39
        if compared < 0:
40
            x.left = self._put(x.left, key, value, d)
41
        elif compared > 0:
42
            x.right = self._put(x.right, key, value, d)
43
        else:
44
            if len(key) - 1 > d:
45
                x.mid = self._put(x.mid, key, value, d + 1)
46
            else:
47
                if x.value is None:
48
                    self.N += 1
49
                x.value = value
50
        return x
51
52
    def get(self, key):
53
        x = self._get(self.root, key, 0)
54
        if x is None:
55
            return None
56
        return x.value
57
58
    def _get(self, x, key, d):
59
        c = char_at(key, d)
60
        if x is None:
61
            return None
62
        compared = c - x.key
63
        if compared < 0:
64
            return self._get(x.left, key, d)
65
        elif compared > 0:
66
            return self._get(x.right, key, d)
67
        else:
68
            if len(key) - 1 > d:
69
                return self._get(x.mid, key, d + 1)
70
            else:
71
                return x
72
73
    def delete(self, key):
74
        self.root = self._delete(self.root, key, 0)
75
76
    def _delete(self, x, key, d):
77
        if x is None:
78
            return None
79
        c = char_at(key, d)
80
        compared = c - x.key
81
        if compared < 0:
82
            x.left = self._delete(x.left, key, d)
83
        elif compared > 0:
84
            x.right = self._delete(x.right, key, d)
85
        else:
86
            if len(key) - 1 > d:
87
                x.mid = self._delete(x.mid, key, d + 1)
88
            else:
89
                self.N -= 1
90
                x = None
91
        return x
92
93
    def contains_key(self, key):
94
        x = self._get(self.root, key, 0)
95
        if x is None:
96
            return False
97
        return True
98
99
    def size(self):
100
        return self.N
101
102
    def is_empty(self):
103
        return self.N == 0
104
105
    def keys(self):
106
        queue = []
107
        self.collect(self.root, '', queue)
108
        return queue
109
110
    def values(self):
111
        queue = []
112
        self.collect_values(self.root, queue)
113
        return queue
114
115
    def collect(self, x, prefix, queue):
116
        if x is None:
117
            return
118
        if x.value is not None:
119
            queue.append(prefix + chr(x.key))
120
        self.collect(x.left, prefix, queue)
121
        self.collect(x.mid, prefix + chr(x.key), queue)
122
        self.collect(x.right, prefix, queue)
123
124
    def collect_values(self, x, queue):
125
        if x is None:
126
            return
127
        if x.value is not None:
128
            queue.append(x.value)
129
130
        self.collect_values(x.left, queue)
131
        self.collect_values(x.mid, queue)
132
        self.collect_values(x.right, queue)
133
134
135
class TernarySearchSet(TernarySearchTrie):
136
    def add(self, key):
137
        self.put(key, 0)
138
139
    def contains(self, key):
140
        return self.contains_key(key)
141
142
    def to_array(self):
143
        return self.keys()
144