Skip to content

Commit c120f38

Browse files
committed
committed from zkp
1 parent 45baada commit c120f38

1 file changed

Lines changed: 114 additions & 0 deletions

File tree

LeetCode/DictADT.py

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
class Array(object):
2+
def __init__(self, size=32, init=None):
3+
self.size = size
4+
self.items = [init] * size
5+
def clear(self, value=None):
6+
for i in range(len(self)):
7+
self.items[i] = value
8+
def __len__(self):
9+
return self.size
10+
def __getitem__(self, index):
11+
return self.items[index]
12+
def __setitem__(self, index, value):
13+
self.items[index] = value
14+
def __iter__(self):
15+
for item in self.items:
16+
yield item
17+
class Slot(object):
18+
def __init__(self, key=None, value=None):
19+
self.key, self.value = key, value
20+
class HashTable(object):
21+
UNUSED = None
22+
EMPTY = Slot()
23+
def __init__(self):
24+
self._table = Array(8, init=HashTable.UNUSED)
25+
self.length = 0
26+
def __len__(self):
27+
return self.length
28+
def _hash(self, key):
29+
return abs(hash(key)) % len(self._table)
30+
@property
31+
def load_factor(self):
32+
return self.length / len(self._table)
33+
def find_key(self, key):
34+
index = self._hash(key)
35+
while self._table[index] is not HashTable.UNUSED:
36+
if self._table[index] is not HashTable.EMPTY and self._table[index].key == key:
37+
return index
38+
index = (index*5+1)%len(self._table)
39+
return None
40+
def find_key_to_insert(self, key):
41+
index = self._hash(key)
42+
while self._table[index] not in (HashTable.UNUSED, HashTable.EMPTY):
43+
index = (index*5+1) % len(self._table)
44+
return index
45+
def add(self, key, value):
46+
if self.find_key(key):
47+
self._table[index].value = value
48+
else:
49+
index = self.find_key_to_insert(key)
50+
slot = Slot(key, value)
51+
self._table[index] = slot
52+
self.length += 1
53+
if self.load_factor >= 0.8:
54+
self._rehash_table()
55+
def _rehash_table(self):
56+
old_table = self._table
57+
newsize = len(self._table) * 2
58+
self._table = Array(newsize, HashTable.UNUSED)
59+
for i in old_table:
60+
if i not in (HashTable.UNUSED, HashTable.EMPTY):
61+
index = self.find_key_to_insert(i.key)
62+
self._table[index] = i
63+
def remove(self, key):
64+
index = self.find_key(key)
65+
if index is not None:
66+
self._table[index] = HashTable.EMPTY
67+
self.length -= 1
68+
else:
69+
raise KeyError('Not Found')
70+
def __iter__(self):
71+
for item in self._table:
72+
if item not in (HashTable.UNUSED, HashTable.EMPTY):
73+
yield (item.key, item.value)
74+
def __contains__(self, key):
75+
if self.find_key(key):
76+
return True
77+
return False
78+
def get(self, key, default=None):
79+
index = self.find_key(key)
80+
if index is not None:
81+
return self._table[index].value
82+
return default
83+
class DictADT(HashTable):
84+
def __setitem__(self, key, value):
85+
self.add(key, value)
86+
def __getitem__(self, key):
87+
return self.get(key)
88+
def items(self):
89+
for item in self:
90+
yield item
91+
def keys(self):
92+
for item in self:
93+
yield item[0]
94+
def values(self):
95+
for item in self:
96+
yield item[1]
97+
def test():
98+
import random
99+
a = DictADT()
100+
a.add('a', 1)
101+
assert len(a) == 1
102+
assert a['a'] == 1
103+
a.remove('a')
104+
assert len(a) == 0
105+
l = list(range(30))
106+
random.shuffle(l)
107+
for i in l:
108+
a[i] = i
109+
assert a[i] == i
110+
assert len(a) == 30
111+
assert sorted(a.values()) == sorted(l)
112+
print('Successful')
113+
if __name__ == "__main__":
114+
test()

0 commit comments

Comments
 (0)