diff --git a/hash_map_sc.py b/hash_map_sc.py index ecd98a7..04830f6 100644 --- a/hash_map_sc.py +++ b/hash_map_sc.py @@ -6,6 +6,7 @@ # Description: HashMap implementation using Separate Chaining +import matplotlib from a6_include import ( DynamicArray, LinkedList, @@ -76,6 +77,26 @@ class HashMap: else: node.value = value + def find_mode_put(self, key: str, value: object) -> None: + """Adds (or updates) a key/value pair to the hash map + + Parameters + ---------- + key : str + Identifier for the given value + value : object + Value to add, or update if the key is already present + """ + + hash = self._hash_function(key) + index = hash % self._capacity + node = self._buckets[index].contains(key) + if node is None: + self._buckets[index].insert(key, value) + self._size += 1 + else: + node.value = node.value + value + def empty_buckets(self) -> int: """Gets the number of empty buckets in the hash table @@ -220,8 +241,21 @@ class HashMap: def find_mode(da: DynamicArray) -> (DynamicArray, int): - """ - TODO: Write this implementation + """Get the mode(s) and their frequency from a dynamic array + + If there is more than one value that has the highest frequency all values at + that frequency will be included. The dynamic array must contain at least 1 + element, and all elements must be strings. + + Parameters + ---------- + da : DynamicArray + The dynamic array for which mode and frequency is needed + + Returns + ------- + (DynamicArray, int) : tuple + Dynamic array with the mode(s), Integer representing highest frequency """ mode_arr = DynamicArray() @@ -229,233 +263,242 @@ def find_mode(da: DynamicArray) -> (DynamicArray, int): mode_arr.append(da[0]) return mode_arr, 1 - # use this instance of your Separate Chaining HashMap map = HashMap(da.length() // 3, hash_function_1) - - item = 1 for i in range(da.length()): - key = "key" + str(item) - map.put(key, da[i]) - item += 1 + map.find_mode_put(da[i], 1) - return -1, -1 + keys = map.get_keys() + max_val = 1 + for i in range(keys.length()): + value = map.get(keys[i]) + if value > max_val: + max_val = value + mode_arr = DynamicArray() + mode_arr.append(keys[i]) + elif value == max_val: + mode_arr.append(keys[i]) + return mode_arr, max_val -# ------------------- BASIC TESTING ---------------------------------------- # + # ------------------- BASIC TESTING ---------------------------------------- # -if __name__ == "__main__": + if __name__ == "__main__": - print("\nPDF - put example 1") - print("-------------------") - m = HashMap(50, hash_function_1) - for i in range(150): - m.put("str" + str(i), i * 100) - if i % 25 == 24: - print(m.empty_buckets(), m.table_load(), m.get_size(), m.get_capacity()) + print("\nPDF - put example 1") + print("-------------------") + m = HashMap(50, hash_function_1) + for i in range(150): + m.put("str" + str(i), i * 100) + if i % 25 == 24: + print(m.empty_buckets(), m.table_load(), m.get_size(), m.get_capacity()) - print("\nPDF - put example 2") - print("-------------------") - m = HashMap(40, hash_function_2) - for i in range(50): - m.put("str" + str(i // 3), i * 100) - if i % 10 == 9: - print(m.empty_buckets(), m.table_load(), m.get_size(), m.get_capacity()) + print("\nPDF - put example 2") + print("-------------------") + m = HashMap(40, hash_function_2) + for i in range(50): + m.put("str" + str(i // 3), i * 100) + if i % 10 == 9: + print(m.empty_buckets(), m.table_load(), m.get_size(), m.get_capacity()) - print("\nPDF - empty_buckets example 1") - print("-----------------------------") - m = HashMap(100, hash_function_1) - print(m.empty_buckets(), m.get_size(), m.get_capacity()) - m.put("key1", 10) - print(m.empty_buckets(), m.get_size(), m.get_capacity()) - m.put("key2", 20) - print(m.empty_buckets(), m.get_size(), m.get_capacity()) - m.put("key1", 30) - print(m.empty_buckets(), m.get_size(), m.get_capacity()) - m.put("key4", 40) - print(m.empty_buckets(), m.get_size(), m.get_capacity()) + print("\nPDF - empty_buckets example 1") + print("-----------------------------") + m = HashMap(100, hash_function_1) + print(m.empty_buckets(), m.get_size(), m.get_capacity()) + m.put("key1", 10) + print(m.empty_buckets(), m.get_size(), m.get_capacity()) + m.put("key2", 20) + print(m.empty_buckets(), m.get_size(), m.get_capacity()) + m.put("key1", 30) + print(m.empty_buckets(), m.get_size(), m.get_capacity()) + m.put("key4", 40) + print(m.empty_buckets(), m.get_size(), m.get_capacity()) - print("\nPDF - empty_buckets example 2") - print("-----------------------------") - m = HashMap(50, hash_function_1) - for i in range(150): - m.put("key" + str(i), i * 100) - if i % 30 == 0: - print(m.empty_buckets(), m.get_size(), m.get_capacity()) + print("\nPDF - empty_buckets example 2") + print("-----------------------------") + m = HashMap(50, hash_function_1) + for i in range(150): + m.put("key" + str(i), i * 100) + if i % 30 == 0: + print(m.empty_buckets(), m.get_size(), m.get_capacity()) - print("\nPDF - table_load example 1") - print("--------------------------") - m = HashMap(100, hash_function_1) - print(m.table_load()) - m.put("key1", 10) - print(m.table_load()) - m.put("key2", 20) - print(m.table_load()) - m.put("key1", 30) - print(m.table_load()) + print("\nPDF - table_load example 1") + print("--------------------------") + m = HashMap(100, hash_function_1) + print(m.table_load()) + m.put("key1", 10) + print(m.table_load()) + m.put("key2", 20) + print(m.table_load()) + m.put("key1", 30) + print(m.table_load()) - print("\nPDF - table_load example 2") - print("--------------------------") - m = HashMap(50, hash_function_1) - for i in range(50): - m.put("key" + str(i), i * 100) - if i % 10 == 0: - print(m.table_load(), m.get_size(), m.get_capacity()) + print("\nPDF - table_load example 2") + print("--------------------------") + m = HashMap(50, hash_function_1) + for i in range(50): + m.put("key" + str(i), i * 100) + if i % 10 == 0: + print(m.table_load(), m.get_size(), m.get_capacity()) - print("\nPDF - clear example 1") - print("---------------------") - m = HashMap(100, hash_function_1) - print(m.get_size(), m.get_capacity()) - m.put("key1", 10) - m.put("key2", 20) - m.put("key1", 30) - print(m.get_size(), m.get_capacity()) - m.clear() - print(m.get_size(), m.get_capacity()) + print("\nPDF - clear example 1") + print("---------------------") + m = HashMap(100, hash_function_1) + print(m.get_size(), m.get_capacity()) + m.put("key1", 10) + m.put("key2", 20) + m.put("key1", 30) + print(m.get_size(), m.get_capacity()) + m.clear() + print(m.get_size(), m.get_capacity()) - print("\nPDF - clear example 2") - print("---------------------") - m = HashMap(50, hash_function_1) - print(m.get_size(), m.get_capacity()) - m.put("key1", 10) - print(m.get_size(), m.get_capacity()) - m.put("key2", 20) - print(m.get_size(), m.get_capacity()) - m.resize_table(100) - print(m.get_size(), m.get_capacity()) - m.clear() - print(m.get_size(), m.get_capacity()) + print("\nPDF - clear example 2") + print("---------------------") + m = HashMap(50, hash_function_1) + print(m.get_size(), m.get_capacity()) + m.put("key1", 10) + print(m.get_size(), m.get_capacity()) + m.put("key2", 20) + print(m.get_size(), m.get_capacity()) + m.resize_table(100) + print(m.get_size(), m.get_capacity()) + m.clear() + print(m.get_size(), m.get_capacity()) - print("\nPDF - resize example 1") - print("----------------------") - m = HashMap(20, hash_function_1) - m.put("key1", 10) - print(m.get_size(), m.get_capacity(), m.get("key1"), m.contains_key("key1")) - m.resize_table(30) - print(m.get_size(), m.get_capacity(), m.get("key1"), m.contains_key("key1")) + print("\nPDF - resize example 1") + print("----------------------") + m = HashMap(20, hash_function_1) + m.put("key1", 10) + print(m.get_size(), m.get_capacity(), m.get("key1"), m.contains_key("key1")) + m.resize_table(30) + print(m.get_size(), m.get_capacity(), m.get("key1"), m.contains_key("key1")) - print("\nPDF - resize example 2") - print("----------------------") - m = HashMap(75, hash_function_2) - keys = [i for i in range(1, 1000, 13)] - for key in keys: - m.put(str(key), key * 42) - print(m.get_size(), m.get_capacity()) + print("\nPDF - resize example 2") + print("----------------------") + m = HashMap(75, hash_function_2) + keys = [i for i in range(1, 1000, 13)] + for key in keys: + m.put(str(key), key * 42) + print(m.get_size(), m.get_capacity()) - for capacity in range(111, 1000, 117): - m.resize_table(capacity) + for capacity in range(111, 1000, 117): + m.resize_table(capacity) - m.put("some key", "some value") - result = m.contains_key("some key") - m.remove("some key") + m.put("some key", "some value") + result = m.contains_key("some key") + m.remove("some key") + for key in keys: + # all inserted keys must be present + result &= m.contains_key(str(key)) + # NOT inserted keys must be absent + result &= not m.contains_key(str(key + 1)) + print( + capacity, + result, + m.get_size(), + m.get_capacity(), + round(m.table_load(), 2), + ) + + print("\nPDF - get example 1") + print("-------------------") + m = HashMap(30, hash_function_1) + print(m.get("key")) + m.put("key1", 10) + print(m.get("key1")) + + print("\nPDF - get example 2") + print("-------------------") + m = HashMap(150, hash_function_2) + for i in range(200, 300, 7): + m.put(str(i), i * 10) + print(m.get_size(), m.get_capacity()) + for i in range(200, 300, 21): + print(i, m.get(str(i)), m.get(str(i)) == i * 10) + print(i + 1, m.get(str(i + 1)), m.get(str(i + 1)) == (i + 1) * 10) + + print("\nPDF - contains_key example 1") + print("----------------------------") + m = HashMap(10, hash_function_1) + print(m.contains_key("key1")) + m.put("key1", 10) + m.put("key2", 20) + m.put("key3", 30) + print(m.contains_key("key1")) + print(m.contains_key("key4")) + print(m.contains_key("key2")) + print(m.contains_key("key3")) + m.remove("key3") + print(m.contains_key("key3")) + + print("\nPDF - contains_key example 2") + print("----------------------------") + m = HashMap(75, hash_function_2) + keys = [i for i in range(1, 1000, 20)] + for key in keys: + m.put(str(key), key * 42) + print(m.get_size(), m.get_capacity()) + result = True for key in keys: # all inserted keys must be present result &= m.contains_key(str(key)) # NOT inserted keys must be absent result &= not m.contains_key(str(key + 1)) - print( - capacity, result, m.get_size(), m.get_capacity(), round(m.table_load(), 2) + print(result) + + print("\nPDF - remove example 1") + print("----------------------") + m = HashMap(50, hash_function_1) + print(m.get("key1")) + m.put("key1", 10) + print(m.get("key1")) + m.remove("key1") + print(m.get("key1")) + m.remove("key4") + + print("\nPDF - get_keys example 1") + print("------------------------") + m = HashMap(10, hash_function_2) + for i in range(100, 200, 10): + m.put(str(i), str(i * 10)) + print(m.get_keys()) + + m.resize_table(1) + print(m.get_keys()) + + m.put("200", "2000") + m.remove("100") + m.resize_table(2) + print(m.get_keys()) + + print("\nPDF - find_mode example 1") + print("-----------------------------") + da = DynamicArray(["apple", "apple", "grape", "melon", "melon", "peach"]) + map = HashMap(da.length() // 3, hash_function_1) + mode, frequency = find_mode(da) + print(f"Input: {da}\nMode: {mode}, Frequency: {frequency}") + + print("\nPDF - find_mode example 2") + print("-----------------------------") + test_cases = ( + [ + "Arch", + "Manjaro", + "Manjaro", + "Mint", + "Mint", + "Mint", + "Ubuntu", + "Ubuntu", + "Ubuntu", + "Ubuntu", + ], + ["one", "two", "three", "four", "five"], + ["2", "4", "2", "6", "8", "4", "1", "3", "4", "5", "7", "3", "3", "2"], ) - print("\nPDF - get example 1") - print("-------------------") - m = HashMap(30, hash_function_1) - print(m.get("key")) - m.put("key1", 10) - print(m.get("key1")) - - print("\nPDF - get example 2") - print("-------------------") - m = HashMap(150, hash_function_2) - for i in range(200, 300, 7): - m.put(str(i), i * 10) - print(m.get_size(), m.get_capacity()) - for i in range(200, 300, 21): - print(i, m.get(str(i)), m.get(str(i)) == i * 10) - print(i + 1, m.get(str(i + 1)), m.get(str(i + 1)) == (i + 1) * 10) - - print("\nPDF - contains_key example 1") - print("----------------------------") - m = HashMap(10, hash_function_1) - print(m.contains_key("key1")) - m.put("key1", 10) - m.put("key2", 20) - m.put("key3", 30) - print(m.contains_key("key1")) - print(m.contains_key("key4")) - print(m.contains_key("key2")) - print(m.contains_key("key3")) - m.remove("key3") - print(m.contains_key("key3")) - - print("\nPDF - contains_key example 2") - print("----------------------------") - m = HashMap(75, hash_function_2) - keys = [i for i in range(1, 1000, 20)] - for key in keys: - m.put(str(key), key * 42) - print(m.get_size(), m.get_capacity()) - result = True - for key in keys: - # all inserted keys must be present - result &= m.contains_key(str(key)) - # NOT inserted keys must be absent - result &= not m.contains_key(str(key + 1)) - print(result) - - print("\nPDF - remove example 1") - print("----------------------") - m = HashMap(50, hash_function_1) - print(m.get("key1")) - m.put("key1", 10) - print(m.get("key1")) - m.remove("key1") - print(m.get("key1")) - m.remove("key4") - - print("\nPDF - get_keys example 1") - print("------------------------") - m = HashMap(10, hash_function_2) - for i in range(100, 200, 10): - m.put(str(i), str(i * 10)) - print(m.get_keys()) - - m.resize_table(1) - print(m.get_keys()) - - m.put("200", "2000") - m.remove("100") - m.resize_table(2) - print(m.get_keys()) - - print("\nPDF - find_mode example 1") - print("-----------------------------") - da = DynamicArray(["apple", "apple", "grape", "melon", "melon", "peach"]) - map = HashMap(da.length() // 3, hash_function_1) - mode, frequency = find_mode(da) - print(f"Input: {da}\nMode: {mode}, Frequency: {frequency}") - - print("\nPDF - find_mode example 2") - print("-----------------------------") - test_cases = ( - [ - "Arch", - "Manjaro", - "Manjaro", - "Mint", - "Mint", - "Mint", - "Ubuntu", - "Ubuntu", - "Ubuntu", - "Ubuntu", - ], - ["one", "two", "three", "four", "five"], - ["2", "4", "2", "6", "8", "4", "1", "3", "4", "5", "7", "3", "3", "2"], - ) - - for case in test_cases: - da = DynamicArray(case) - map = HashMap(da.length() // 3, hash_function_2) - mode, frequency = find_mode(da) - print(f"Input: {da}\nMode: {mode}, Frequency: {frequency}\n") + for case in test_cases: + da = DynamicArray(case) + map = HashMap(da.length() // 3, hash_function_2) + mode, frequency = find_mode(da) + print(f"Input: {da}\nMode: {mode}, Frequency: {frequency}\n")