diff --git a/u7/hash_table.py b/u7/hash_table.py index d458cc4..1d5236c 100644 --- a/u7/hash_table.py +++ b/u7/hash_table.py @@ -2,10 +2,11 @@ class HashTable: _DELETED = object() def __init__(self, capacity=10): + """Vytvor prázdnu tabuľku s kladnou celočíselnou kapacitou.""" if type(capacity) is not int: - raise TypeError("Capacity must be an integer") + raise TypeError("It's not integer") if capacity <= 0: - raise ValueError("Capacity must be positive") + raise ValueError("Capacity > 0") self._capacity = capacity self._table = [None] * capacity @@ -13,29 +14,30 @@ class HashTable: @property def capacity(self): + """Vráť aktuálny počet pozícií v poli.""" return self._capacity - def _validate_key(self, key): + def hash(self, key): + """Vráť polynomiálny hash kľúča modulo aktuálna kapacita.""" if not isinstance(key, str): raise TypeError("Key must be a string") - def hash(self, key): - self._validate_key(key) - h = 0 - for char in key: - h = (31 * h + ord(char)) % self.capacity + for znak in key: + h = (31 * h + ord(znak)) % self.capacity return h def probe(self, key): - self._validate_key(key) + """Vráť index kľúča alebo miesta na vloženie bez zmeny tabuľky.""" + if not isinstance(key, str): + raise TypeError("Key must be a string") start = self.hash(key) first_deleted = None - for step in range(self.capacity): - index = (start + step) % self.capacity + for krok in range(self.capacity): + index = (start + krok) % self.capacity item = self._table[index] if item is None: @@ -54,28 +56,13 @@ class HashTable: raise RuntimeError("Hash table is full") - def __setitem__(self, key, value): - self._validate_key(key) - - index = self.probe(key) - item = self._table[index] - - # Existujúci kľúč: prepíš hodnotu. - if item is not None and item is not self._DELETED: - if item[0] == key: - self._table[index] = (key, value) - return - - # Nový kľúč: skontroluj zaplnenie. - if (self._size + 1) / self.capacity > 0.7: - self._resize(self.capacity * 2) - index = self.probe(key) - - self._table[index] = (key, value) - self._size += 1 + def load_factor(self): + """Vráť podiel počtu aktívnych položiek a kapacity.""" + return self._size / self.capacity def __getitem__(self, key): - self._validate_key(key) + if not isinstance(key, str): + raise TypeError("Key must be a string") index = self.probe(key) item = self._table[index] @@ -85,8 +72,30 @@ class HashTable: return item[1] + def __setitem__(self, key, value): + if not isinstance(key, str): + raise TypeError("Key must be a string") + + index = self.probe(key) + item = self._table[index] + + # Ak kľúč existuje, prepíš iba jeho hodnotu. + if item is not None and item is not self._DELETED: + if item[0] == key: + self._table[index] = (key, value) + return + + # Ak nový kľúč prekročí zaplnenie 0.7, zväčši tabuľku. + if (self._size + 1) / self.capacity > 0.7: + self._resize(self.capacity * 2) + index = self.probe(key) + + self._table[index] = (key, value) + self._size += 1 + def __delitem__(self, key): - self._validate_key(key) + if not isinstance(key, str): + raise TypeError("Key must be a string") index = self.probe(key) item = self._table[index] @@ -98,9 +107,14 @@ class HashTable: self._size -= 1 def __contains__(self, key): - self._validate_key(key) + if not isinstance(key, str): + raise TypeError("Key must be a string") + + try: + index = self.probe(key) + except RuntimeError: + return False - index = self.probe(key) item = self._table[index] return ( @@ -117,10 +131,8 @@ class HashTable: if item is not None and item is not self._DELETED: yield item[0] - def load_factor(self): - return self._size / self.capacity - def _resize(self, new_capacity): + """Zväčši tabuľku a vlož všetky aktívne položky nanovo.""" old_table = self._table self._capacity = new_capacity