avp26/u7/hash_table.py
2026-10-29 22:19:29 +01:00

93 lines
3.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Hash tabuľka s lineárnym sondovaním a reťazcovými kľúčmi."""
class HashTable:
def __init__(self, capacity=10):
"""Vytvor prázdnu tabuľku s kladnou celočíselnou kapacitou."""
if not isinstance(capacity, int) or isinstance(capacity, bool): # бо булл по факту теж 1 або 0
raise TypeError("kapacita ma byt cele cislo")
if capacity <= 0:
raise ValueError("kapacita ma byt + a cela")
self.empty = object()# позначка що позиція ніколи не використовувалась
self.deleted = object() # позначка шо тут був елемент, його видалили
self._capacity = capacity
self.size = 0
self.table = []# саме сховище позицій
for i in range(capacity):
self.table.append(self.empty)
@property
def capacity(self):
"""Vráť aktuálny počet pozícií v poli."""
return self._capacity
def hash(self, key):
"""Vráť polynomiálny hash kľúča modulo aktuálna kapacita."""
if not isinstance(key, str):
raise TypeError("kluc ma byt retaz")
result = 0
for char in str(key):
result = result * 31 + ord(char)
return result % self.capacity
def probe(self, key):
"""Vráť index kľúča alebo miesta na vloženie bez zmeny tabuľky."""
if not isinstance(key, str):
raise TypeError("kluc ma byt retaz")
i = 0
del_slot = None
while i < self.capacity:
index = (self.hash(key) + i) % self.capacity
if self.table[index] is self.empty: # Дійшли до порожнього місця: ключа в таблиці точно нема
if del_slot is None:
return index
else:
return del_slot
elif self.table[index] is self.deleted: # Видалений слот: запам'ятовуємо лише перший і йдемо далі
if del_slot is None:
del_slot = index
elif self.table[index][0] == key:
return index
i += 1
if del_slot is not None:
return del_slot
else:
raise RuntimeError("tabula je povna")
#raise KeyError(key)
def load_factor(self):
"""Vráť podiel počtu aktívnych položiek a kapacity."""
return self.size / self.capacity if self._capacity > 0 else 0
def __getitem__(self, key):
index = self.probe(key)
return self.table[index][1]
def __setitem__(self, key, value):
index = self.probe(key)
if self.table[index] is self.empty:
self.size += 1
self.table[index] = (key, value)
def __delitem__(self, key):
index = self.probe(key)
if self.table[index] is self.empty or self.table[index] is self.deleted:
raise KeyError(key)
self.table[index] = self.deleted
self.size -= 1
def __contains__(self, key):
if self.table[self.probe(key)] is self.empty or self.table[self.probe(key)] is self.deleted:
return False
else:
return True
def __len__(self):
return self.size
def __iter__(self):
for bucket in self.table:
if bucket is not self.empty and bucket is not self.deleted:
yield bucket[0]