Skip to content

Commit 158fe01

Browse files
committed
committed from zkp
1 parent a803434 commit 158fe01

File tree

1 file changed

+95
-0
lines changed

1 file changed

+95
-0
lines changed

LeetCode/hashtable.py

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
class Array(object):
2+
def __init__(self, size=30, init=None):
3+
self.size = size
4+
self.items = [init]*size
5+
def __getitem__(self, index):
6+
return self.items[index]
7+
def __setitem__(self, index, value):
8+
self.items[index] = value
9+
def __len__(self):
10+
return self.size
11+
def clear(self):
12+
for i in range(len(self.size)):
13+
self.items[i] = init
14+
def __iter__(self):
15+
for i in self.items:
16+
yield i
17+
class Slot(object):
18+
def __init__(self, value=None, key=None):
19+
self.key, self.value = key, value
20+
class HashTable(object):
21+
EMPTY = None
22+
UNUSED = None
23+
def __init__(self):
24+
self._table = Array(20, HashTable.UNUSED)
25+
self.length = 0
26+
@property
27+
def _load_factor(self):
28+
return self.length / len(self._table)
29+
def __len__(self):
30+
return self.length
31+
def _hash(self, key):
32+
return abs(hash(key)%len(self._table))
33+
def _find_key(self, key):
34+
index = self._hash(key)
35+
_len = self.length
36+
while self._table[index] is not HashTable.UNUSED:
37+
if self._table[index] is HashTable.EMPTY:
38+
index = (index*5 +1) % _len
39+
continue
40+
elif self._table[index].key == key:
41+
return index
42+
else:
43+
index = (index *5 + 1) / _len
44+
return None
45+
def _slot_can_insert(self, index):
46+
return (self._table[index] is HashTable.EMPTY or HashTable.UNUSED)
47+
def _find_slots_for_insert(self, key):
48+
index = self._hash(key)
49+
_len = self.length
50+
while not _slot_can_insert(index):
51+
index = (index*5 +1)%_len
52+
return index
53+
def __contains__(self, key):
54+
index = _find_key(key)
55+
return index is not None
56+
def add(self, key, value):
57+
if key in self:
58+
index = self._find_key(key)
59+
self._table[index].value = value
60+
return False
61+
else:
62+
index = _find_slots_for_insert(key)
63+
self._table[index] = Slot(value, key)
64+
self.length += 1
65+
if self._load_factor() >= 0.8:
66+
self._rehash()
67+
return True
68+
def rehash(self):
69+
old_table = self._table
70+
newsize = len(self) * 2
71+
self._table = Array(newsize, HashTable.UNUSED)
72+
self.length = 0
73+
for slot in old_table:
74+
if slot is not HashTable.UNUSED and slot is not HashTable.EMPTY:
75+
index = self._find_slots_for_insert(slot.key)
76+
self._table[index] = slot
77+
self.length += 1
78+
def get(self, key, default=None):
79+
index = self._find_key(key)
80+
if index is None:
81+
return default
82+
else:
83+
return self._table[index].value
84+
def remove(self, key):
85+
index = self._find_key(key)
86+
if index is None:
87+
raise KeyError()
88+
value = self._table[index].value
89+
self._table[index].key = HashTable.EMPTY
90+
self.length -= 1
91+
return value
92+
def __iter__(self):
93+
for slot in self._table:
94+
if slot not in (HashTable.EMPTY, HashTable.UNUSED):
95+
yield slot.key

0 commit comments

Comments
 (0)