From c51ba44a983ac9a05947eab0ad86c47088172ea4 Mon Sep 17 00:00:00 2001 From: julien lengrand-lambert Date: Tue, 26 Nov 2013 18:55:16 +0100 Subject: [PATCH] Adds _HashMapItem object that will be used to properly handle collisions. Also adds documentation to the first HM implementation --- 02_hash_maps/hm.py | 83 +++++++++++++++++++++++++++------------------- 1 file changed, 49 insertions(+), 34 deletions(-) diff --git a/02_hash_maps/hm.py b/02_hash_maps/hm.py index d9175ca..faeff91 100644 --- a/02_hash_maps/hm.py +++ b/02_hash_maps/hm.py @@ -7,12 +7,27 @@ Collisions are not handled in this version. 2013/11 """ +class _HashMapItem(): + """ + Hashmap items are the objects that will be contained in my Hashmaps. + They permit to find the correct value back, even in case of collision. + Not all of my HashMap implementations use HMItems. + """ + def __init__(self, key, value): + self.k = key + self.v = value + class HashMap(): + """ + This implementation does NOT use _HashMapItems + Also, this implementation will return an error in case of a collision. + Data will not be lost, but another key will have to be used. + """ def __init__(self, hash_size=513): self._hash_size = hash_size self._size = 0 self.hmap = [None] * self._hash_size - + def add(self, key, value): """ Adds the provided value to the hashmap. @@ -22,96 +37,96 @@ class HashMap(): if self.hmap[my_key] == None: self.hmap[my_key] = value self._size += 1 - else: + else: raise Exception("Collision detected at index %d", key) - + def get(self, key): """ - Finds the element in the hash table that may contain the id for + Finds the element in the hash table that may contain the id for the string we are looking for """ my_key = self._hash(key) - return self.hmap[my_key] - + return self.hmap[my_key] + def size(self): return self._size - + def _hash(self, value): """ Generates a hash for the given value. The input is expected to be a String, with only ASCII characters. - + # hash function taken from HT3. # We shift and add : << 4 is a *16 """ if len(value) < 1: raise Exception("Size of value must be greater than one") - + h = 0 for letter in value: h = (h << 4) + ord(letter) - + return h % self._hash_size class HMTableCollision(HashMap): """ Extension of the previous HashMap implementation that takes care of collisions. - Instead of having only one slot available per index in the table, - each index will contain a list. This means several elements can be + Instead of having only one slot available per index in the table, + each index will contain a list. This means several elements can be stored with the same index. """ def __init__(self, hash_size=513): self._hash_size = hash_size self._size = 0 self.hmap = [None] * self._hash_size - + def add(self, key, value): """ Adds the provided value to the hashmap. Raises an Exception if a collision is detected """ my_key = self._hash(key) - + if self.hmap[my_key] == None: self.hmap[my_key] = [value] - else: + else: self.hmap[my_key].append(value) self._size += 1 - + def get(self, key): """ - Finds the element in the hash table that may contain the id for + Finds the element in the hash table that may contain the id for the string we are looking for """ my_key = self._hash(key) vals = self.hmap[my_key] - + if vals is None: return vals elif len(vals) == 1: - return vals[0] + return vals[0] else: return vals # we return all the results if there are several - + def size(self): return self._size - + def _hash(self, value): """ Generates a hash for the given value. The input is expected to be a String, with only ASCII characters. - + # hash function taken from HT3. # We shift and add : << 4 is a *16 """ if len(value) < 1: raise Exception("Size of value must be greater than one") - + h = 0 for letter in value: h = (h << 4) + ord(letter) - + return h % self._hash_size class HMNeighbourCollision(): @@ -119,7 +134,7 @@ class HMNeighbourCollision(): self._hash_size = hash_size self._size = 0 self.hmap = [None] * self._hash_size - + def add(self, key, value): """ Adds the provided value to the hashmap. @@ -127,7 +142,7 @@ class HMNeighbourCollision(): """ my_key = self._hash(key) idx = self._find_free_idx(my_key) - + self.hmap[idx] = value self._size += 1 @@ -139,7 +154,7 @@ class HMNeighbourCollision(): idx = key cur_ptr = 1 negative = True - + while(True): if self.hmap[idx] == None: return idx @@ -151,30 +166,30 @@ class HMNeighbourCollision(): idx = key + cur_ptr negative = True cur_ptr += 1 - + def get(self, key): """ - Finds the element in the hash table that may contain the id for + Finds the element in the hash table that may contain the id for the string we are looking for """ #TODO - + def size(self): return self._size - + def _hash(self, value): """ Generates a hash for the given value. The input is expected to be a String, with only ASCII characters. - + # hash function taken from HT3. # We shift and add : << 4 is a *16 """ if len(value) < 1: raise Exception("Size of value must be greater than one") - + h = 0 for letter in value: h = (h << 4) + ord(letter) - + return h % self._hash_size