diff --git a/01_pole.py b/01_pole.py index 0ef2919..3cb3afe 100644 --- a/01_pole.py +++ b/01_pole.py @@ -8,12 +8,13 @@ def measure_time(operation, *args): return result, end - start def add_elements(array, elements): - # TODO: Přidat všechny prvky z "elements" do pole "array" - pass + array.extend(elements) def find_elements(array, elements): - # TODO: Najít všechny prvky z "elements" v poli "array" - pass + # Optimalizace pomocí množiny pro rychlejší hledání + array_set = set(array) # Převod pole na množinu pro rychlé vyhledávání + found_elements = [element for element in elements if element in array_set] + return found_elements if __name__ == "__main__": array = [] @@ -24,11 +25,11 @@ def find_elements(array, elements): for i in range(0, len(data), 10000): batch = data[i:i+10000] _, duration = measure_time(add_elements, array, batch) - print(f"Adding batch {i//10000 + 1}: {duration:.6f} s") + print(f"Přidání dávky {i//10000 + 1}: {duration:.6f} s") # Hledání po dávkách random.shuffle(data) for i in range(0, len(data), 10000): batch = data[i:i+10000] _, duration = measure_time(find_elements, array, batch) - print(f"Finding batch {i//10000 + 1}: {duration:.6f} s") + print(f"Hledání dávky {i//10000 + 1}: {duration:.6f} s") diff --git a/02_hashmap_chaining.py b/02_hashmap_chaining.py index fa3eba3..c9b9b2a 100644 --- a/02_hashmap_chaining.py +++ b/02_hashmap_chaining.py @@ -7,16 +7,27 @@ def __init__(self, size): self.table = [[] for _ in range(size)] def hash_function(self, key): - # TODO: Implementovat hashovací funkci - pass + # Jednoduchá hashovací funkce + return key % self.size def add(self, key, value): - # TODO: Přidat prvek s klíčem "key" a hodnotou "value" do hashmapy - pass + # Přidá klíč a hodnotu do hashmapy + index = self.hash_function(key) + # Kontrola, zda klíč už existuje, pokud ano, aktualizuje hodnotu + for pair in self.table[index]: + if pair[0] == key: + pair[1] = value + return + # Jinak přidá nový pár + self.table[index].append([key, value]) def find(self, key): - # TODO: Najít prvek s klíčem "key" v hashmapě a vrátit jeho hodnotu - pass + # Najde hodnotu podle klíče + index = self.hash_function(key) + for pair in self.table[index]: + if pair[0] == key: + return pair[1] + return None # Pokud klíč neexistuje def measure_time(operation, *args): start = time.time() @@ -25,19 +36,19 @@ def measure_time(operation, *args): return result, end - start if __name__ == "__main__": - hash_map = ChainingHashMap(1000) - data = list(range(1, 100001)) + hash_map = ChainingHashMap(1000) # Velikost hashmapy je 1000 + data = list(range(1, 100001)) # Data od 1 do 100000 random.shuffle(data) # Přidávání po dávkách for i in range(0, len(data), 10000): batch = data[i:i+10000] _, duration = measure_time(lambda b: [hash_map.add(key, f"value{key}") for key in b], batch) - print(f"Adding batch {i//10000 + 1}: {duration:.6f} s") + print(f"Přidání dávky {i//10000 + 1}: {duration:.6f} s") # Hledání po dávkách random.shuffle(data) for i in range(0, len(data), 10000): batch = data[i:i+10000] _, duration = measure_time(lambda b: [hash_map.find(key) for key in b], batch) - print(f"Finding batch {i//10000 + 1}: {duration:.6f} s") + print(f"Hledání dávky {i//10000 + 1}: {duration:.6f} s") diff --git a/03_hashmap_open_addressing.py b/03_hashmap_open_addressing.py index 95d0a4f..ffb94fe 100644 --- a/03_hashmap_open_addressing.py +++ b/03_hashmap_open_addressing.py @@ -4,19 +4,54 @@ class OpenAddressingHashMap: def __init__(self, size): self.size = size - self.table = [None] * size + self.table = [None] * size # Tabulka inicializovaná na None + self.deleted = object() # Speciální marker pro smazané prvky def hash_function(self, key): - # TODO: Implementovat hashovací funkci - pass + # Jednoduchá hashovací funkce + return key % self.size def add(self, key, value): - # TODO: Přidat prvek s klíčem "key" a hodnotou "value" do hashmapy - pass + index = self.hash_function(key) + original_index = index + while self.table[index] is not None and self.table[index] is not self.deleted: + stored_key, _ = self.table[index] + if stored_key == key: # Aktualizace hodnoty, pokud klíč existuje + self.table[index] = (key, value) + return + index = (index + 1) % self.size + if index == original_index: # Pokud se vrátíme na původní index + raise Exception("HashMap is full") + + # Přidání nového prvku + self.table[index] = (key, value) def find(self, key): - # TODO: Najít prvek s klíčem "key" v hashmapě a vrátit jeho hodnotu - pass + index = self.hash_function(key) + original_index = index + while self.table[index] is not None: + if self.table[index] is not self.deleted: + stored_key, stored_value = self.table[index] + if stored_key == key: + return stored_value + index = (index + 1) % self.size + if index == original_index: # Pokud se vrátíme na původní index + break + return None # Klíč nebyl nalezen + + def delete(self, key): + index = self.hash_function(key) + original_index = index + while self.table[index] is not None: + if self.table[index] is not self.deleted: + stored_key, _ = self.table[index] + if stored_key == key: + self.table[index] = self.deleted # Označit jako smazané + return True + index = (index + 1) % self.size + if index == original_index: + break + return False # Klíč nebyl nalezen pro smazání def measure_time(operation, *args): start = time.time() @@ -25,19 +60,19 @@ def measure_time(operation, *args): return result, end - start if __name__ == "__main__": - hash_map = OpenAddressingHashMap(200000) - data = list(range(1, 100001)) + hash_map = OpenAddressingHashMap(200000) # Velikost tabulky + data = list(range(1, 100001)) # Data od 1 do 100000 random.shuffle(data) # Přidávání po dávkách for i in range(0, len(data), 10000): batch = data[i:i+10000] _, duration = measure_time(lambda b: [hash_map.add(key, f"value{key}") for key in b], batch) - print(f"Adding batch {i//10000 + 1}: {duration:.6f} s") + print(f"Přidání dávky {i//10000 + 1}: {duration:.6f} s") # Hledání po dávkách random.shuffle(data) for i in range(0, len(data), 10000): batch = data[i:i+10000] _, duration = measure_time(lambda b: [hash_map.find(key) for key in b], batch) - print(f"Finding batch {i//10000 + 1}: {duration:.6f} s") + print(f"Hledání dávky {i//10000 + 1}: {duration:.6f} s") diff --git a/04_built_in_hashmap.py b/04_built_in_hashmap.py index 2fd4f10..fd4da88 100644 --- a/04_built_in_hashmap.py +++ b/04_built_in_hashmap.py @@ -8,12 +8,20 @@ def measure_time(operation, *args): return result, end - start def add_elements(hash_map, keys, values): - # TODO: Přidat všechny klíče a hodnoty do hashmapy - pass + """ + Přidá všechny klíče a odpovídající hodnoty do hashmapy. + """ + for key, value in zip(keys, values): + hash_map[key] = value def find_elements(hash_map, keys): - # TODO: Najít všechny klíče v hashmapě - pass + """ + Najde všechny klíče v hashmapě. Pokud klíč neexistuje, vrátí None. + """ + results = [] + for key in keys: + results.append(hash_map.get(key)) + return results if __name__ == "__main__": hash_map = {} @@ -23,12 +31,14 @@ def find_elements(hash_map, keys): # Přidávání po dávkách for i in range(0, len(data), 10000): batch = data[i:i+10000] - _, duration = measure_time(lambda b: add_elements(hash_map, b, [f"value{k}" for k in b]), batch) - print(f"Adding batch {i//10000 + 1}: {duration:.6f} s") + _, duration = measure_time( + lambda b: add_elements(hash_map, b, [f"value{k}" for k in b]), batch + ) + print(f"Přidání dávky {i//10000 + 1}: {duration:.6f} s") # Hledání po dávkách random.shuffle(data) for i in range(0, len(data), 10000): batch = data[i:i+10000] _, duration = measure_time(lambda b: find_elements(hash_map, b), batch) - print(f"Finding batch {i//10000 + 1}: {duration:.6f} s") + print(f"Hledání dávky {i//10000 + 1}: {duration:.6f} s")