Passed
Push — master ( cc5b0d...7501fb )
by Xianshun
01:21
created

SearchTries.keysWithPrefix()   A

Complexity

Conditions 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
c 1
b 0
f 0
dl 0
loc 3
rs 10
1
from abc import ABCMeta, abstractmethod
2
3
from pyalgs.data_structures.commons.queue import Queue
4
5
6
class SearchTries(object):
7
    __metaclass__ = ABCMeta
8
9
    @abstractmethod
10
    def put(self, key, value):
11
        pass
12
13
    @abstractmethod
14
    def get(self, key):
15
        pass
16
17
    @abstractmethod
18
    def is_empty(self):
19
        pass
20
21
    @abstractmethod
22
    def size(self):
23
        pass
24
25
    @abstractmethod
26
    def delete(self, key):
27
        pass
28
29
    @abstractmethod
30
    def keys(self):
31
        pass
32
33
    @abstractmethod
34
    def keysWithPrefix(self, prefix):
35
        pass
36
37
    @abstractmethod
38
    def contains_key(self, key):
39
        pass
40
41
    @staticmethod
42
    def create():
43
        return RWaySearchTries()
44
45
46
class Node(object):
47
    nodes = None
48
    value = None
49
    R = 256
50
51
    def __init__(self):
52
        self.nodes = [None] * Node.R
53
54
55
class RWaySearchTries(SearchTries):
56
57
    root = None
58
    N = 0
59
60
    def contains_key(self, key):
61
        x = self._get(self.root, key, 0)
62
        if x is None:
63
            return None
64
        return x.value
65
66
    def keysWithPrefix(self, prefix):
67
        x = self._get(self.root, prefix, 0)
68
        if x is None:
69
            return None
70
71
        queue = Queue.create()
72
        self.collect(x, prefix, queue)
73
        return queue.iterate()
74
75
    def keys(self):
76
        queue = Queue.create()
77
        self.collect(self.root, '', queue)
78
        return queue.iterate()
79
80
    def collect(self, x, prefix, queue):
81
        if x is None:
82
            return
83
84
        if x.value is not None:
85
            queue.enqueue(prefix)
86
            return
87
88
        for r in range(Node.R):
89
            self.collect(x.nodes[r], prefix + str(chr(r)), queue)
90
91
    def is_empty(self):
92
        return self.N == 0
93
94
    def get(self, key):
95
        x = self._get(self.root, key, 0)
96
        if x is not None:
97
            return x.value
98
        return None
99
100
    def _get(self, x, key, d):
101
        if x is None:
102
            return None
103
        if len(key) == d:
104
            return x
105
106
        return self._get(x.nodes[self.char_at(key, d)], key, d + 1)
107
108
    def delete(self, key):
109
        self.root = self._delete(self.root, key, 0)
110
111
    def _delete(self, x, key, d):
112
        if x is None:
113
            return None
114
115
        if len(key) == d:
116
            if x.value is not None:
117
                self.N -= 1
118
            return None
119
120
        c = self.char_at(key, d)
121
        x.nodes[c] = self._delete(x.nodes[c], key, d + 1)
122
        return x
123
124
    def put(self, key, value):
125
        self.root = self._put(self.root, key, value, 0)
126
127
    def _put(self, x, key, value, d):
128
        if x is None:
129
            x = Node()
130
        if len(key) == d:
131
            if x.value is None:
132
                self.N += 1
133
            x.value = value
134
            return x
135
136
        c = self.char_at(key, d)
137
        x.nodes[c] = self._put(x.nodes[c], key, value, d + 1)
138
        return x
139
140
    def char_at(self, key, d):
141
        return ord(key[d])
142
143
    def size(self):
144
        return self.N
145