-
Notifications
You must be signed in to change notification settings - Fork 623
Expand file tree
/
Copy pathhash_table.py
More file actions
145 lines (118 loc) · 4.53 KB
/
hash_table.py
File metadata and controls
145 lines (118 loc) · 4.53 KB
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
"""
Create a hash table from scratch. Use chaining for hash collision
"""
# the size will be such that it will start size small and when full it will copy everything to the new bigger sized table
class HashTable:
class __node:
def __init__(self,val,next = None):
self.val = val
self.next = next
def __eq__(self, other):
# Use self.__class__ so it's always the same node type
if not isinstance(other, self.__class__):
return False
return self.val == other.val
def __init__(self):
self.__curr_size = 1000
self.__hash_table = [None] * self.__curr_size
def __insert(self,key,value):
hash_value = self.hash_function(key)
index = hash_value%self.__curr_size
temp =self.__node((key,value))# so i can identify which node have the value
if self.__hash_table[index] is None:
self.__hash_table[index] = temp
else:
head = self.__hash_table[index]
prev = head
curr = head.next
while curr is not None:
curr = curr.next
prev = prev.next
assert prev.next is None
prev.next = temp
def __delete(self,ele):
hash_value = self.hash_function(ele)
index = hash_value%self.__curr_size
if self.__hash_table[index] is None:
return
else:
prev = None
head = self.__hash_table[index]
while head is not None:
if head.val[0]==ele:
nex = head.next
while nex is not None:
head.val = nex.val
prev = head
head = head.next
nex = nex.next
if prev is None:
# first element
temp = head.next
head.next = None
self.__hash_table = temp
else:
assert head.next is None
prev.next = None
del head
return
prev = head
head = head.next
return
def __get(self,ele):
"""access the value of ele = key"""
hash_value = self.hash_function(ele)
index = hash_value%self.__curr_size
if self.__hash_table[index] == None:
raise KeyError
head = self.__hash_table[index]
while head is not None:
if head.val[0] == ele:
return head.val[1]
head = head.next
raise KeyError
def hash_function(self,ele):
"""return hash value for the ele"""
# should support all data type such as tup int float str bool
def for_int_float(ele):
return (ele*10)+(pow(ele,2)//7) + ele
def for_str(ele):
integer = 0
k = 1
for i in ele:
integer += k*(ord(i))
k += 1
ele = integer
return (ele*10)+(pow(ele,2)//7) + ele
def for_tup(ele,total = 0):
for i in ele:
if isinstance(i,(int,float)):
answer = for_int_float(i)
elif isinstance(i,str):
answer = for_str(i)
elif isinstance(i,tuple):
answer = for_tup(i,total+1)
else:
raise Exception(f"UNHASHABLE ITEM {ele}")
total += answer
return total
if isinstance(ele,(int,float)):
return for_int_float(ele)
elif isinstance(ele,str):
return for_str(ele)
elif isinstance(ele,tuple):
return for_tup(ele)
else:
raise Exception(f"UNHASHABLE ITEM {ele}")
def __setitem__(self, key, value):
self.__insert(key,value)
def __getitem__(self,key):
return(self.__get(key))
def __delete__(self,key):
self.__delete(key)
def __contains__(self,item):
try:
self.__get(item)
return True
except KeyError:
return False