Aktualizovat u7/hash_table.py

This commit is contained in:
Oleksandr Mateshchuk 2026-10-29 18:26:40 +00:00
parent 375babbc41
commit 60f922f2ef

View File

@ -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