class BloomFilter: def __init__(self, size=10): # DO NOT EDIT THIS CONSTRUCTOR self.size = size self.array = FixedSizeArray(size) for i in range(0, size): self.array.set(i, False) # Adds an element to the bloom filter using three hash functions. def add_elem(self, elem): # raise NotImplementedError hash1 = cs5112_hash1(elem) % self.size hash2 = cs5112_hash2(elem) % self.size hash3 = cs5112_hash3(elem) % self.size for j in [hash1, hash2, hash3]: self.array.set(j, True) # Returns False if the given element is was definitely not added to the # filter. Returns True if it's possible that the element was added to the # filter (but not necessarily certain). def check_membership(self, elem): # raise NotImplementedError hash1 = cs5112_hash1(elem) % self.size hash2 = cs5112_hash2(elem) % self.size hash3 = cs5112_hash3(elem) % self.size counter = 0 for k in [hash1, hash2, hash3]: if self.array.get(k): counter += 1 if counter == 0: return False else: return True
def __init__(self, initial_size=10, load_factor=.75): # DO NOT EDIT THIS CONSTRUCTOR if (initial_size < 0) or (load_factor <= 0) or (load_factor > 1): raise Exception("size must be greater than zero, and load factor must be between 0 and 1") self.array_size = initial_size self.load_factor = load_factor self.item_count = 0 self.array = FixedSizeArray(initial_size)
def _resize_array(self): array_size = self.array_size * 2 oldArray = self.array self.array_size = array_size self.array = FixedSizeArray(array_size) self.item_count = 0 # fixed sized array has a list of items. for i in oldArray.items: if i is not None and i != 'x': self.insert(i[0], i[1])
class BloomFilter: def __init__(self, size=10): # DO NOT EDIT THIS CONSTRUCTOR self.size = size self.array = FixedSizeArray(size) for i in range(0, size): self.array.set(i, False) # Adds an element to the bloom filter using three hash functions. def add_elem(self, elem): self.array.set(cs5112_hash1(elem) % self.size, True) self.array.set(cs5112_hash2(elem) % self.size, True) self.array.set(cs5112_hash3(elem) % self.size, True) # Returns False if the given element is was definitely not added to the # filter. Returns True if it's possible that the element was added to the # filter (but not necessarily certain). def check_membership(self, elem): hash1 = cs5112_hash1(elem) % self.size hash2 = cs5112_hash2(elem) % self.size hash3 = cs5112_hash3(elem) % self.size if self.array.get(hash1) and self.array.get(hash2) and self.array.get( hash3): return True return False
class BloomFilter: def __init__(self, size=10): # DO NOT EDIT THIS CONSTRUCTOR self.size = size self.array = FixedSizeArray(size) for i in range(0, size): self.array.set(i, False) # To add an element to the bloom filter, use each of the k=3 hash functions we provided and compute # the positions that we are setting in the fixed size array using modulo operation. def add_elem(self, elem): p1 = cs5112_hash1(elem) % self.size p2 = cs5112_hash2(elem) % self.size p3 = cs5112_hash3(elem) % self.size self.array.set(p1, True) self.array.set(p2, True) self.array.set(p3, True) # Returns False if the given element was definitely not added to the filter. # Returns True if it's possible that the element was added to the filter. def check_membership(self, elem): p1 = cs5112_hash1(elem) % self.size p2 = cs5112_hash2(elem) % self.size p3 = cs5112_hash3(elem) % self.size if not self.array.get(p1) or not self.array.get( p2) or not self.array.get(p3): return False return True
def _resize_array(self): self.array_size *= 2 self.item_count = 0 self.total_item_count = 0 prev_arr = self.array self.array = FixedSizeArray(self.array_size) for i in xrange(self.array_size / 2): if prev_arr.get(i) is None: continue k, v, in_use = prev_arr.get(i) if in_use: self.insert(k, v)
def _resize_array(self): # YOUR CODE HERE orgsize = self.array_size orgarray = self.array self.array_size *= 2 self.array = FixedSizeArray(self.array_size) self.item_count = 0 for i in range(orgsize): orgelem = orgarray.get(i) if orgelem != None: self.insert(orgelem[0],orgelem[1])
class BloomFilter: def __init__(self, size=10): # DO NOT EDIT THIS CONSTRUCTOR self.size = size self.array = FixedSizeArray(size) for i in range(0, size): self.array.set(i, False) # To add an element to the bloom filter, use each of the k=3 hash functions we provided and compute # the positions that we are setting in the fixed size array using modulo operation. def add_elem(self, elem): #TODO: YOUR CODE HERE, delete the line below and implement accordingly self.array.set(cs5112_hash1(elem) % 10, True) self.array.set(cs5112_hash2(elem) % 10, True) self.array.set(cs5112_hash3(elem) % 10, True) # Returns False if the given element was definitely not added to the filter. # Returns True if it's possible that the element was added to the filter. def check_membership(self, elem): #TODO: YOUR CODE HERE, delete the line below and implement accordingly if (self.array.get(cs5112_hash1(elem) % 10) and self.array.get(cs5112_hash2(elem) % 10) and self.array.get(cs5112_hash3(elem) % 10)): return True else: return False
def _resize_array(self): self.array_size *= 2 self.item_count = 0 prev_arr = self.array self.array = FixedSizeArray(self.array_size) for i in xrange(self.array_size / 2): if prev_arr.get(i) is None: continue cur_list = prev_arr.get(i) for n in self._iterate_list(cur_list): k, v = n.get_value() self.insert(k, v)
def _resize_array(self): # YOUR CODE HERE self.array_size *= 2 oldArray = self.array self.array = FixedSizeArray(self.array_size) for i in range(0, oldArray.size): if oldArray.get(i) != None: h = cs5112_hash1(oldArray.get(i)[0]) % self.array_size while self.array.get(h) is not None: h = (h + 1) % self.array_size self.array.set(h, (oldArray.get(i)[0], oldArray.get(i)[1]))
def _resize_array(self): new_array_size = 2 * self.array_size new_array = FixedSizeArray(new_array_size) for i in range(self.array_size): if self.array.get(i) is None or self.array.get(i)[2]: continue new_hash_index = cs5112_hash1( self.array.get(i)[0]) % new_array_size while new_array.get( new_hash_index ) is not None: # for a new array, we do not consider deleted case new_hash_index = (new_hash_index + 1) % new_array_size new_array.set(new_hash_index, self.array.get(i)) self.array = new_array self.array_size = new_array_size
def _resize_array(self): # create new array new_array = FixedSizeArray(self.array_size * 2) temp_array = [] # temp array # loop through fixed array current elems for elem in self.array.items: # temporarily store all elements into list if elem: temp_array.append(elem) self.array = new_array # set array to new empty array self.array_size = self.array_size * 2 # set new size variable self.item_count = 0 # reset item count # reinsert each elem in temp array into new FixedSizedArray for elem in temp_array: # need to loop through entire linked list and reinsert each node while elem: key, value = elem.get_value() # retrieve the tuple self.insert(key, value) # insert into new array elem = elem.get_next()
def _resize_array(self): tupList = [] # Iterate through all of the items in the previous array and add to a list for i in range(self.array_size): node = self.array.get(i) while (node != None): tupList.append(node.get_value()) node = node.get_next() # Replace self.array with the new array self.array = FixedSizeArray(self.array_size * 2) self.array_size *= 2 self.item_count = 0 # Iterate through the list of tuples and add them back for (k, v) in tupList: self.insert(k, v)
def _resize_array(self): new_array_size = 2 * self.array_size new_array = FixedSizeArray(new_array_size) for i in range(self.array_size): if self.array.get(i) is None: continue node = self.array.get(i) while node is not None: new_index = cs5112_hash1(node.get_value()[0]) % new_array_size new_node = new_array.get(new_index) if new_node is None: new_array.set(new_index, SLLNode(node.get_value())) else: while new_node.get_next() is not None: new_node = new_node.get_next() new_node.set_next(SLLNode(node.get_value())) self.array = new_array self.array_size = new_array_size
def _resize_array(self): new_length = self.array_size * 2 self.item_count = 0 old_arr = self._get_array() self.array = FixedSizeArray(new_length) self.array_size = new_length for i in range(old_arr.size): if old_arr.get(i) is not None: val = old_arr.get(i) self.insert(val[0], val[1])
def _resize_array(self): # store old array here temp. temp = [] # loop through old array for ind in range(self.array_size): # if entry is not empty, save it in temp if self.array.get(ind) and self.array.get(ind) != 'removed': key, value = self.array.get(ind) # retrieve the elem temp.append((key, value)) self.array_size *= 2 # double size self.item_count = 0 # reset count to 0 # make new array self.array = FixedSizeArray(self.array_size) # loop through temp array and reinsert into new array for elem in temp: key, value = elem # unpack it self.insert(key, value)
def _resize_array(self): new_length = self.array_size * 2 self.item_count = 0 old_arr = self._get_array() self.array = FixedSizeArray(new_length) self.array_size = new_length for i in range(old_arr.size): if old_arr.get(i) is not None: val = old_arr.get(i) cur_node = val.head while (cur_node != None): kv = cur_node.get_value() k = kv[0] v = kv[1] self.insert(k, v) cur_node = cur_node.get_next()
class BloomFilter: def __init__(self, size=10): # DO NOT EDIT THIS CONSTRUCTOR self.size = size self.array = FixedSizeArray(size) for i in range(0, size): self.array.set(i, False) # Adds an element to the bloom filter using three hash functions. def add_elem(self, elem): # If elem is None, raise an Exception if (elem == None): raise ValueError("Key can't be None") # Calculate the hashes for a given element. h1 = cs5112_hash1(elem) % self.size h2 = cs5112_hash2(elem) % self.size h3 = cs5112_hash3(elem) % self.size # Set True at h1, h2, and h3. self.array.set(h1, True) self.array.set(h2, True) self.array.set(h3, True) # Returns False if the given element was definitely not added to the # filter. Returns True if it's possible that the element was added to the # filter (but not necessarily certain). def check_membership(self, elem): # If elem is None, raise an Exception if (elem == None): raise ValueError("Key can't be None") # Calculate the hashes for a given element. h1 = cs5112_hash1(elem) % self.size h2 = cs5112_hash2(elem) % self.size h3 = cs5112_hash3(elem) % self.size return (self.array.get(h1) and self.array.get(h2) and self.array.get(h3))
class BloomFilter: def __init__(self, size=10): # DO NOT EDIT THIS CONSTRUCTOR self.size = size self.array = FixedSizeArray(size) for i in range(0, size): self.array.set(i, False) # To add an element to the bloom filter, use each of the k=3 hash functions we provided and compute # the positions that we are setting in the fixed size array using modulo operation. def add_elem(self, elem): index1 = cs5112_hash1(elem) % self.size index2 = cs5112_hash2(elem) % self.size index3 = cs5112_hash3(elem) % self.size print(index1, index2, index3) # set indices to True self.array.set(index1, True) self.array.set(index2, True) self.array.set(index3, True) # Returns False if the given element was definitely not added to the filter. # Returns True if it's possible that the element was added to the filter. def check_membership(self, elem): index1 = cs5112_hash1(elem) % self.size index2 = cs5112_hash2(elem) % self.size index3 = cs5112_hash3(elem) % self.size print(index1, index2, index3) value1 = self.array.get(index1) value2 = self.array.get(index2) value3 = self.array.get(index3) print(value1, value2, value3) # if all these indices are set to True in the bit array -> probably present (True) result = value1 and value2 and value3 return result
class HashTable: def __init__(self, initial_size=10, load_factor=.75): # DO NOT EDIT THIS CONSTRUCTOR if (initial_size < 0) or (load_factor <= 0) or (load_factor > 1): raise Exception( "size must be greater than zero, and load factor must be between 0 and 1" ) self.array_size = initial_size self.load_factor = load_factor self.item_count = 0 self.array = FixedSizeArray(initial_size) # ============ We mark a flag for DELETION ============ # Inserts the `(key, value)` pair into the hash table, overwriting any value # previously associated with `key`. # Note: Neither `key` nor `value` may be None (an exception will be raised) def insert(self, key, value): # first search self.item_count += 1 if (self.item_count * 1.0 / self.array_size) > self.load_factor: self._resize_array() hash_key = cs5112_hash1(key) % self.array_size #condtion: hash_key is not empty while self.array.get(hash_key) is not None: # condition 1: rewrite, same key and haven't been deleted if self.array.get( hash_key)[0] == key and not self.array.get(hash_key)[2]: self.item_count -= 1 self.array.set(hash_key, (key, value, False)) return #condition 2: rewrite, same key but been deleted elif self.array.get(hash_key)[0] == key and self.array.get( hash_key)[2]: self.array.set(hash_key, (key, value, False)) return #condition 3: empty space, but still need to search for the rest elif self.array.get(hash_key)[2]: self.array.set(hash_key, (key, value, False)) hash_key = (hash_key + 1) % self.array_size while self.array.get(hash_key) is not None: if self.array.get(hash_key)[0] == key: self.item_count -= 1 self.array.set( hash_key, (key, self.array.get(hash_key)[1], True)) return hash_key = (hash_key + 1) % self.array_size self.array.set(hash_key, (key, value, False)) return # while self.array.get(hash_key) is not None\ # and self.array.get(hash_key)[0] != key\ # and not self.array.get(hash_key)[2]: # not deleted # hash_key = (hash_key + 1) % self.array_size # # if there is an vacant array in the middle, just reset it # # if previously key is associated, just replace it # if self.array.get(hash_key) is not None and \ # self.array.get(hash_key)[0] == key: # overwrite case # self.item_count -= 1 # self.array.set(hash_key, (key, value, False)) # return # accelerate # self.array.set(hash_key, (key, value, False)) # # Delete previously entry with the same key # hash_key = (hash_key + 1) % self.array_size # while self.array.get(hash_key) is not None: # if self.array.get(hash_key)[0] == key: # self.array.set(hash_key, (key, value, True)) # break # hash_key = (hash_key + 1) % self.array_size # Returns the value associated with `key` in the hash table, or None if no # such value is found. # Note: `key` may not be None (an exception will be raised) def get(self, key): hash_key = cs5112_hash1(key) % self.array_size while self.array.get(hash_key) is not None: if not self.array.get(hash_key)[2] and self.array.get( hash_key)[0] == key: return self.array.get(hash_key)[1] hash_key += 1 return None # Removed start var since we will not search the whole array # for the worst case hash(value) = constant: # since the load factor < 1, there must be some None in the array [never has elements] # start = hash_key # while self.array.get(hash_key)[0] != key: # TODO: if the entry is None, it will cause Exception # hash_key += 1 # if hash_key == start: # return None # return self.array.get(hash_key)[1] # Removes the `(key, value)` pair matching the given `key` from the map, if it # exists. If such a pair exists in the map, the return value will be the value # that was removed. If no such value exists, the method will return None. # Note: `key` may not be None (an exception will be raised) def remove(self, key): if self.item_count == 0: return None # add a corner case to accelerate # self.item_count -= 1 # TODO: if non-exist, count should not -1 # search for the entry first hash_key = cs5112_hash1(key) % self.array_size while self.array.get(hash_key) is not None: if not self.array.get(hash_key)[2] and self.array.get( hash_key)[0] == key: value = self.array.get(hash_key)[1] # mark the entry as deleted self.array.set(hash_key, (key, value, True)) self.item_count -= 1 return value return None # start = hash_key # while self.array.get(hash_key) is None or self.array.get(hash_key)[0] != key: # # TODO: time complexity is O(array_size) which could be optimized at least to O(array_size * load_factor) # hash_key = (hash_key + 1) % self.array_size # if hash_key == start: # return None # return_val = self.array.get(hash_key)[1] # self.array.set(hash_key, None) # return return_val # Returns the number of elements in the hash table. def size(self): return self.item_count # Internal helper function for resizing the hash table's array once the ratio # of stored mappings to array size exceeds the specified load factor. def _resize_array(self): new_array_size = 2 * self.array_size new_array = FixedSizeArray(new_array_size) for i in range(self.array_size): if self.array.get(i) is None or self.array.get(i)[2]: continue new_hash_index = cs5112_hash1( self.array.get(i)[0]) % new_array_size while new_array.get( new_hash_index ) is not None: # for a new array, we do not consider deleted case new_hash_index = (new_hash_index + 1) % new_array_size new_array.set(new_hash_index, self.array.get(i)) self.array = new_array self.array_size = new_array_size # Internal helper function for accessing the array underlying the hash table. def _get_array(self): # DO NOT EDIT THIS METHOD return self.array
class HashTable: def __init__(self, initial_size=10, load_factor=.75): # DO NOT EDIT THIS CONSTRUCTOR if (initial_size < 0) or (load_factor <= 0) or (load_factor > 1): raise Exception( "size must be greater than zero, and load factor must be between 0 and 1" ) self.array_size = initial_size self.load_factor = load_factor self.item_count = 0 self.array = FixedSizeArray(initial_size) # Inserts the `(key, value)` pair into the hash table, overwriting any value # previously associated with `key`. # Note: Neither `key` nor `value` may be None (an exception will be raised) def insert(self, key, value): # Raise exception if either key or value is None if (key == None or value == None): raise ValueError("Neither Key nor Value can be None") h = cs5112_hash1(key) % self.array_size # If nothing exists at this location, just insert, increment if self.array.get(h) == None: self.array.set(h, (key, value)) self.item_count += 1 else: # Iterate through the next elements until you reach a None, update if you see the same key while self.array.get(h) != None: if self.array.get(h)[0] == key: self.array.set(h, (key, value)) return h = (h + 1) % self.array_size # Insert value at this None self.array.set(h, (key, value)) self.item_count += 1 # If the load factor now exceeds the limit, resize if ((float(self.item_count) / self.array_size) > self.load_factor): self._resize_array() # Returns the value associated with `key` in the hash table, or None if no # such value is found. # Note: `key` may not be None (an exception will be raised) def get(self, key): # If key is None, raise an Exception if (key == None): raise ValueError("Key can't be None") h = cs5112_hash1(key) % self.array_size if self.array.get(h) == None: return None while self.array.get(h) != None: if self.array.get(h)[0] == key: return self.array.get(h)[1] h = (h + 1) % self.array_size return None # Removes the `(key, value)` pair matching the given `key` from the map, if it # exists. If such a pair exists in the map, the return value will be the value # that was removed. If no such value exists, the method will return None. # Note: `key` may not be None (an exception will be raised) def remove(self, key): # If key is None, raise an Exception if (key == None): raise ValueError("Key can't be None") h = cs5112_hash1(key) % self.array_size result = None # If None at that hash table value can return immedietely if self.array.get(h) == None: return None # Iterate through array to check for key matches while self.array.get(h) != None: if self.array.get(h)[0] == key: result = self.array.get(h)[1] self.array.set(h, None) self.item_count -= 1 break h = (h + 1) % self.array_size # If result is found, need to reinsert next if result != None: tupList = [] curr = (h + 1) % self.array_size while (self.array.get(curr) != None): tupList.append(self.array.get(curr)) self.array.set(curr, None) self.item_count -= 1 curr = (curr + 1) % self.array_size for (k, v) in tupList: self.insert(k, v) return result # Returns the number of elements in the hash table. def size(self): # YOUR CODE HERE return self.item_count # Internal helper function for resizing the hash table's array once the ratio # of stored mappings to array size exceeds the specified load factor. def _resize_array(self): # YOUR CODE HERE self.array_size *= 2 oldArray = self.array self.array = FixedSizeArray(self.array_size) for i in range(0, oldArray.size): if oldArray.get(i) != None: h = cs5112_hash1(oldArray.get(i)[0]) % self.array_size while self.array.get(h) is not None: h = (h + 1) % self.array_size self.array.set(h, (oldArray.get(i)[0], oldArray.get(i)[1])) # Internal helper function for accessing the array underlying the hash table. def _get_array(self): # DO NOT EDIT THIS METHOD return self.array # def printArray(self): # print("[", end = '') # for i in range(self.array_size): # print(str(self.array.get(i))+", ", end = '') # print("]") # return
class BloomFilter: def __init__(self, size=10): # DO NOT EDIT THIS CONSTRUCTOR self.size = size self.array = FixedSizeArray(size) for i in range(0, size): self.array.set(i, False) # To add an element to the bloom filter, use each of the k=3 hash functions we provided and compute # the positions that we are setting in the fixed size array using modulo operation. def add_elem(self, elem): #TODO: YOUR CODE HERE, delete the line below and implement accordingly hash_1 = cs5112_hash1(elem) hash_1_res_rightmost = hash_1 % self.size self.array.set(hash_1_res_rightmost, True) hash_2 = cs5112_hash2(elem) hash_2_res_rightmost = hash_2 % self.size self.array.set(hash_2_res_rightmost, True) hash_3 = cs5112_hash3(elem) hash_3_res_rightmost = hash_3 % self.size self.array.set(hash_3_res_rightmost, True) #hash_res = cs5112_hash3(cs5112_hash2(cs5112_hash1(elem))) #hash_res_rightmost = hash_res % 10 # while (hash_res > 0): # hash_res_rightmost = hash_res % 10 # self.array.set(hash_res_rightmost, True) # hash_res = hash_res / 10 # Returns False if the given element was definitely not added to the filter. # Returns True if it's possible that the element was added to the filter. def check_membership(self, elem): #TODO: YOUR CODE HERE, delete the line below and implement accordingly hash_1 = cs5112_hash1(elem) hash_1_res_rightmost = hash_1 % self.size bool1 = self.array.get(hash_1_res_rightmost) hash_2 = cs5112_hash2(elem) hash_2_res_rightmost = hash_2 % self.size bool2 = self.array.get(hash_2_res_rightmost) hash_3 = cs5112_hash3(elem) hash_3_res_rightmost = hash_3 % self.size bool3 = self.array.get(hash_3_res_rightmost) if (bool1 and bool2 and bool3): return True return False
class HashTable: def __init__(self, initial_size=10, load_factor=.75): # DO NOT EDIT THIS CONSTRUCTOR if (initial_size < 0) or (load_factor <= 0) or (load_factor > 1): raise Exception( "size must be greater than zero, and load factor must be between 0 and 1" ) self.array_size = initial_size self.load_factor = load_factor self.item_count = 0 self.array = FixedSizeArray(initial_size) # Inserts the `(key, value)` pair into the hash table, overwriting any value # previously associated with `key`. # Note: Neither `key` nor `value` may be None (an exception will be raised) def insert(self, key, value): if key is None or value is None: raise Exception("key and value cannot be None") in_arr = self.get(key) is not None if not in_arr: self.item_count += 1 ind = cs5112_hash1(key) % self.array_size cur_list = self.array.get(ind) if cur_list is None: self.array.set(ind, SLLNode((key, value), None)) else: # see if it's already in the list for n in self._iterate_list(cur_list): k, _ = n.get_value() if k is key: n.set_value((key, value)) return # it isn't already in the list self._list_get_last(cur_list).set_next(SLLNode((key, value), None)) if self._get_current_load() >= self.load_factor: self._resize_array() # Returns the value associated with `key` in the hash table, or None if no # such value is found. # Note: `key` may not be None (an exception will be raised) def get(self, key): if key is None: raise Exception("key cannot be None") ind = cs5112_hash1(key) % self.array_size cur_list = self.array.get(ind) # list doesn't exist, value must not be stored if cur_list is None: return None # search through list for n in self._iterate_list(cur_list): k, v = n.get_value() if k == key: return v # value was not found return None # Removes the `(key, value)` pair matching the given `key` from the map, if it # exists. If such a pair exists in the map, the return value will be the value # that was removed. If no such value exists, the method will return None. # Note: `key` may not be None (an exception will be raised) def remove(self, key): if key is None: raise Exception("Key cannot be None") ind = cs5112_hash1(key) % self.array_size cur_list = self.array.get(ind) ret_val = None # if the list is None, we definitely don't have the value stored if cur_list is None: return None # first item in linked list if cur_list.get_value()[0] == key: ret_val = cur_list.get_value()[1] self.item_count -= 1 self.array.set(ind, cur_list.get_next()) else: # search through the list to see if the key is in it for n in self._iterate_list(cur_list): if n == None: # it isn't in the list return None next_node = n.get_next() if next_node == None: return None k, v = next_node.get_value() if k == key: # found the key, so store the value ret_val = v self.item_count -= 1 n.set_next(next_node.get_next()) return ret_val return ret_val # Returns the number of elements in the hash table. def size(self): return self.item_count # Internal helper function for resizing the hash table's array once the ratio # of stored mappings to array size exceeds the specified load factor. def _resize_array(self): self.array_size *= 2 self.item_count = 0 prev_arr = self.array self.array = FixedSizeArray(self.array_size) for i in xrange(self.array_size / 2): if prev_arr.get(i) is None: continue cur_list = prev_arr.get(i) for n in self._iterate_list(cur_list): k, v = n.get_value() self.insert(k, v) # Internal helper function for accessing the array underlying the hash table. def _get_array(self): # DO NOT EDIT THIS FUNCTION return self.array def _get_current_load(self): return float(self.item_count) / self.array_size # generator for linked lists def _iterate_list(self, first_node): node = first_node while node != None: yield node node = node.get_next() def _list_get_last(self, node): while node.get_next() != None: node = node.get_next() return node
class HashTable: def __init__(self, initial_size=10, load_factor=.75): # DO NOT EDIT THIS CONSTRUCTOR if (initial_size < 0) or (load_factor <= 0) or (load_factor > 1): raise Exception( "size must be greater than zero, and load factor must be between 0 and 1" ) self.array_size = initial_size self.load_factor = load_factor self.item_count = 0 self.array = FixedSizeArray(initial_size) # Inserts the `(key, value)` pair into the hash table, overwriting any value # previously associated with `key`. # Note: Neither `key` nor `value` may be None (an exception will be raised) def insert(self, key, value): # if key or value is None, raise an Exception if (key == None or value == None): raise ValueError("Neither Key nor Value can be None") # Get the hash value and take the modulus hashval = cs5112_hash1(key) % self.array_size # If there is nothing at that entry in the array, create the first node and inc count if (self.array.get(hashval) == None): newNode = SLLNode((key, value)) self.array.set(hashval, newNode) self.item_count += 1 else: # If something already exists, iterate through and see if any match the key node = self.array.get(hashval) prevNode = None while (node != None): # If so, update the value and don't change the count if (node.get_value()[0] == key): node.set_value((key, value)) return prevNode = node node = node.get_next() # Else at the end add the node and inc the count newNode = SLLNode((key, value), None) prevNode.set_next(newNode) self.item_count += 1 # If the load factor now exceeds the limit, resize if ((float(self.item_count) / self.array_size) > self.load_factor): self._resize_array() # Returns the value associated with `key` in the hash table, or None if no # such value is found. # Note: `key` may not be None (an exception will be raised) def get(self, key): # If key is None, raise an Exception if (key == None): raise ValueError("Key can't be None") # Get hash value and mod it hashval = cs5112_hash1(key) % self.array_size node = self.array.get(hashval) # While 'node' isn't None, search through while (node != None): if (node.get_value()[0] == key): return node.get_value()[1] node = node.get_next() # Else return None return None # Removes the `(key, value)` pair matching the given `key` from the map, if it # exists. If such a pair exists in the map, the return value will be the value # that was removed. If no such value exists, the method will return None. # Note: `key` may not be None (an exception will be raised) def remove(self, key): # If key is None, raise an Exception if (key == None): raise ValueError("Key can't be None") # Get hash value and mod it hashval = cs5112_hash1(key) % self.array_size node = self.array.get(hashval) # Can't remove it if it doesn't exist if (node == None): return None # If it is the first element of the linked list, set that pointer to the next if (node.get_value()[0] == key): self.array.set(hashval, node.get_next()) self.item_count -= 1 return node.get_value()[1] prevNode = node node = node.get_next() # While 'node' isn't None, search through while (node != None): # If it is found further down the list, set the previous node's # pointer to the next node and return the value if (node.get_value()[0] == key): prevNode.set_next(node.get_next()) self.item_count -= 1 return node.get_value()[1] prevNode = node node = node.get_next() # Else return None return None # Returns the number of elements in the hash table. def size(self): return self.item_count # Internal helper function for resizing the hash table's array once the ratio # of stored mappings to array size exceeds the specified load factor. def _resize_array(self): tupList = [] # Iterate through all of the items in the previous array and add to a list for i in range(self.array_size): node = self.array.get(i) while (node != None): tupList.append(node.get_value()) node = node.get_next() # Replace self.array with the new array self.array = FixedSizeArray(self.array_size * 2) self.array_size *= 2 self.item_count = 0 # Iterate through the list of tuples and add them back for (k, v) in tupList: self.insert(k, v) # Internal helper function for accessing the array underlying the hash table. def _get_array(self): # DO NOT EDIT THIS FUNCTION return self.array # Helper print function to investigate inner workings of structure # def printArray(self): # print("[", end = '') # for i in range(self.array_size): # node = self.array.get(i) # if (node == None): # print("None, ", end='') # while (node != None): # print(node.get_value(),end='') # node = node.get_next() # if (node != None): # print("->",end='') # else: # print(", ",end='') # print("]") # return
class HashTable: def __init__(self, initial_size=10, load_factor=.75): # DO NOT EDIT THIS CONSTRUCTOR if (initial_size < 0) or (load_factor <= 0) or (load_factor > 1): raise Exception("size must be greater than zero, and load factor must be between 0 and 1") self.array_size = initial_size self.load_factor = load_factor self.item_count = 0 self.array = FixedSizeArray(initial_size) # Inserts the `(key, value)` pair into the hash table, overwriting any value # previously associated with `key`. # Note: Neither `key` nor `value` may be None (an exception will be raised) def insert(self, key, value): # YOUR CODE HERE if key == None: raise Exception('Key cannot be None!') if value == None: raise Exception('Value cannot be None!') k = cs5112_hash1(key)%self.array_size pointer = self.array.get(k) node = SLLNode((key,value)) if pointer==None: self.array.set(k, node) else: while pointer.get_next()!= None: if pointer.get_value()[0]== key: pointer.set_value((key,value)) return pointer = pointer.get_next() pointer.set_next(node) self.item_count += 1 # if self.item_count/self.array_size >= self.load_factor: # self._resize_array() # Returns the value associated with `key` in the hash table, or None if no # such value is found. # Note: `key` may not be None (an exception will be raised) def get(self, key): # YOUR CODE HERE if key == None: raise Exception('Key cannot be None!') k = cs5112_hash1(key)%self.array_size start = self.array.get(k) while start != None and start.get_value()!= None: if start.get_value()[0] == key: return start.get_value()[1] start = start.get_next() return None # Removes the `(key, value)` pair matching the given `key` from the map, if it # exists. If such a pair exists in the map, the return value will be the value # that was removed. If no such value exists, the method will return None. # Note: `key` may not be None (an exception will be raised) def remove(self, key): # YOUR CODE HERE # REWRITE!!! if key == None: raise Exception('Key cannot be None!') k = cs5112_hash1(key)%self.array_size prev = curr = self.array.get(k) if curr != None: while curr.get_next()!= None: if curr.get_value()[0]== key: if curr.get_next()==None: prev.set_next(None) else: prev.set_next(curr.get_next()) self.item_count-=1 return curr.get_value() else: prev = curr curr = curr.get_next() else: return None # Returns the number of elements in the hash table. def size(self): # YOUR CODE HERE # raise NotImplementedError() return self.item_count # Internal helper function for resizing the hash table's array once the ratio # of stored mappings to array size exceeds the specified load factor. def _resize_array(self): # YOUR CODE HERE orgsize = self.array_size orgarray = self.array self.array_size *= 2 self.array = FixedSizeArray(self.array_size) self.item_count = 0 for i in range(orgsize): orgelem = orgarray.get(i) if orgelem != None: self.insert(orgelem[0],orgelem[1]) # Internal helper function for accessing the array underlying the hash table. def _get_array(self): # DO NOT EDIT THIS FUNCTION return self.array
class HashTable: def __init__(self, initial_size=10, load_factor=.75): # DO NOT EDIT THIS CONSTRUCTOR if (initial_size < 0) or (load_factor <= 0) or (load_factor > 1): raise Exception("size must be greater than zero, and load factor must be between 0 and 1") self.array_size = initial_size self.load_factor = load_factor self.item_count = 0 self.array = FixedSizeArray(initial_size) # Inserts the `(key, value)` pair into the hash table, overwriting any value # previously associated with `key`. # Note: Neither `key` nor `value` may be None (an exception will be raised) def insert(self, key=None, value=None): try: if key is None or value is None: raise TypeError ind = cs5112_hash1(key) % self.array.size head = self.array.get(ind) while head != None: if head.get_value()[0] == key: head.set_value((key, value)) return head = head.get_next() self.item_count += 1 # print("SIZE after insert = " + str(self.item_count)) head = self.array.get(ind) new_node = SLLNode((key,value)) new_node.set_next(head) self.array.set(ind, new_node) if (self.item_count / self.array.size) > self.load_factor: temp_arr = self.array self._resize_array() self.item_count = 0 for i in range(temp_arr.size): oldhead = temp_arr.get(i) while oldhead != None: self.insert(oldhead.get_value()[0], oldhead.get_value()[1]) oldhead = oldhead.get_next() except TypeError: print('Key and/or value cannot be None!') # Returns the value associated with `key` in the hash table, or None if no # such value is found. # Note: `key` may not be None (an exception will be raised) def get(self, key=None): try: if key is None: raise TypeError ind = cs5112_hash1(key) % self.array.size head = self.array.get(ind) while head != None: if head.get_value()[0] == key: return head.get_value()[1] head = head.get_next() return None except TypeError: print('Key cannot be None!') # Removes the `(key, value)` pair matching the given `key` from the map, if it # exists. If such a pair exists in the map, the return value will be the value # that was removed. If no such value exists, the method will return None. # Note: `key` may not be None (an exception will be raised) def remove(self, key): try: if key is None: raise TypeError ind = cs5112_hash1(key) % self.array_size head = self.array.get(ind) prev = None print("HEAD = " + str(head)) while head != None: if head.get_value()[0] == key: break prev = head head = head.get_next() if not head: return None self.item_count -= 1 if prev != None: prev.set_next(head.get_next()) else: self.array.set(ind, head.get_next()) return head.get_value()[1] except TypeError: print('Key cannot be None!') # Returns the number of elements in the hash table. def size(self): return self.item_count # Internal helper function for resizing the hash table's array once the ratio # of stored mappings to array size exceeds the specified load factor. def _resize_array(self): self.array = FixedSizeArray(2 * self.array.size) self.array_size *= 2 # Internal helper function for accessing the array underlying the hash table. def _get_array(self): # DO NOT EDIT THIS FUNCTION return self.array
class HashTable: def __init__(self, initial_size=10, load_factor=.75): # DO NOT EDIT THIS CONSTRUCTOR if (initial_size < 0) or (load_factor <= 0) or (load_factor > 1): raise Exception( "size must be greater than zero, and load factor must be between 0 and 1" ) self.array_size = initial_size self.load_factor = load_factor self.item_count = 0 self.array = FixedSizeArray(initial_size) # Inserts the `(key, value)` pair into the hash table, overwriting any value # previously associated with `key`. # Note: Neither `key` nor `value` may be None (an exception will be raised) def insert(self, key, value): if key is None or value is None: raise Exception # resizing if more than load factor if (self.item_count / self.array_size) > self.load_factor: self._resize_array() index = cs5112_hash1(key) % self.array_size # if index is not empty, it is either x or real tuple while self._get_array().get(index) is not None: # if it is x, it is removed. add it here. if self._get_array().get(index) == 'x': self._get_array().set(index, (key, value)) self.item_count += 1 break # the key is the same, just update the value elif self._get_array().get(index)[0] == key: self._get_array().set(index, (key, value)) break else: # there is a real, other tuple, move on # wrap-around logic if self.array_size - 1 == index: index = 0 # just probe the next cell else: index += 1 if self.array.get(index) is None: self._get_array().set(index, (key, value)) self.item_count += 1 # Returns the value associated with `key` in the hash table, or None if no # such value is found. # Note: `key` may not be None (an exception will be raised) def get(self, key): if key is None: raise Exception index = cs5112_hash1(key) % self.array_size end = index while self._get_array().get(index) is not None: #check that not removed and is the key if self._get_array().get(index) != 'x' and self._get_array().get( index)[0] == key: return self._get_array().get(index)[1] # wrap-around logic if self.array_size - 1 == index: index = 0 else: # just probe the next cell index += 1 if index == end: return None if self._get_array().get(index) is None: return None # Removes the `(key, value)` pair matching the given `key` from the map, if it # exists. If such a pair exists in the map, the return value will be the value # that was removed. If no such value exists, the method will return None. # Note: `key` may not be None (an exception will be raised) def remove(self, key): if key is None: raise Exception index = cs5112_hash1(key) % self.array_size end = index while self._get_array().get(index) is not None: if self._get_array().get(index) != 'x' and self._get_array().get( index)[0] == key: value = self._get_array().get(index)[1] self._get_array().set(index, 'x') self.item_count -= 1 return value # wrap-around logic if self.array_size - 1 == index: index = 0 else: # just probe the next cell index += 1 if index == end: return None return None # Returns the number of elements in the hash table. def size(self): return self.item_count # Internal helper function for resizing the hash table's array once the ratio # of stored mappings to array size exceeds the specified load factor. def _resize_array(self): array_size = self.array_size * 2 oldArray = self.array self.array_size = array_size self.array = FixedSizeArray(array_size) self.item_count = 0 # fixed sized array has a list of items. for i in oldArray.items: if i is not None and i != 'x': self.insert(i[0], i[1]) # Internal helper function for accessing the array underlying the hash table. def _get_array(self): # DO NOT EDIT THIS METHOD return self.array
class HashTable: def __init__(self, initial_size=10, load_factor=.75): # DO NOT EDIT THIS CONSTRUCTOR if (initial_size < 0) or (load_factor <= 0) or (load_factor > 1): raise Exception( "size must be greater than zero, and load factor must be between 0 and 1" ) self.array_size = initial_size self.load_factor = load_factor self.item_count = 0 self.array = FixedSizeArray(initial_size) # Inserts the `(key, value)` pair into the hash table, overwriting any value # previously associated with `key`. # Note: Neither `key` nor `value` may be None (an exception will be raised) def insert(self, key, value): # check loading factor, if over, resize if self.load_factor <= (self.item_count / self.array_size): self._resize_array() # hash the key hash_ind = cs5112_hash1(key) % self.array_size # loop until an empty index found while self.array.get(hash_ind) != None and self.array.get( hash_ind) != 'removed': # if you hash and get back the key, then update the value if self.array.get( hash_ind)[0] == key: # check the first entry in the tuple self.array.set(hash_ind, (key, value)) # check hash of next index hash_ind = (hash_ind + 1) % self.array_size # loop broken, found None elem, so set it self.array.set(hash_ind, (key, value)) self.item_count += 1 # Returns the value associated with `key` in the hash table, or None if no # such value is found. # Note: `key` may not be None (an exception will be raised) def get(self, key): # hash the key hash_ind = cs5112_hash1(key) % self.array_size # loop through non empty cells while self.array.get(hash_ind) != None: elem = self.array.get(hash_ind) # get the elem # if the elem is not removed, check it's key, value # else, just continue searching if elem != 'removed': # if you hash and get back the key if elem[0] == key: # check key in tuple return elem[1] # second entry is value # get hash of next index hash_ind = (hash_ind + 1) % self.array_size # if looped through and no match, return None return None # Removes the `(key, value)` pair matching the given `key` from the map, if it # exists. If such a pair exists in the map, the return value will be the value # that was removed. If no such value exists, the method will return None. # Note: `key` may not be None (an exception will be raised) def remove(self, key): # hash the key hash_ind = cs5112_hash1(key) % self.array_size # loop through non empty cells while self.array.get(hash_ind) != None: elem = self.array.get(hash_ind) # if you hash and get back the key if elem[0] == key: # check the first entry in the tuple self.array.set(hash_ind, 'removed') self.item_count -= 1 # decrement return elem # get hash of next index hash_ind = (hash_ind + 1) % self.array_size # if looped through and no match, return None return None # Returns the number of elements in the hash table. def size(self): return self.item_count # Internal helper function for resizing the hash table's array once the ratio # of stored mappings to array size exceeds the specified load factor. def _resize_array(self): # store old array here temp. temp = [] # loop through old array for ind in range(self.array_size): # if entry is not empty, save it in temp if self.array.get(ind) and self.array.get(ind) != 'removed': key, value = self.array.get(ind) # retrieve the elem temp.append((key, value)) self.array_size *= 2 # double size self.item_count = 0 # reset count to 0 # make new array self.array = FixedSizeArray(self.array_size) # loop through temp array and reinsert into new array for elem in temp: key, value = elem # unpack it self.insert(key, value) # Internal helper function for accessing the array underlying the hash table. def _get_array(self): # DO NOT EDIT THIS METHOD return self.array
def __init__(self, size=10): # DO NOT EDIT THIS CONSTRUCTOR self.size = size self.array = FixedSizeArray(size) for i in range(0, size): self.array.set(i, False)
def _resize_array(self): self.array = FixedSizeArray(2 * self.array.size) self.array_size *= 2