hash functions added

This commit is contained in:
gabriel 2018-03-20 20:48:58 -03:00
parent aa8485b4df
commit 1fa23f57d7
7 changed files with 202 additions and 0 deletions

View File

@ -0,0 +1,6 @@
from .hash_table import HashTable
class QuadraticProbing(HashTable):
def __init__(self):
super(self.__class__, self).__init__()

View File

@ -0,0 +1,33 @@
#!/usr/bin/env python3
from .hash_table import HashTable
from number_theory.prime_numbers import next_prime, check_prime
class DoubleHash(HashTable):
"""
Hash Table example with open addressing and Double Hash
"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
def __hash_function_2(self, value, data):
next_prime_gt = next_prime(value % self.size_table) \
if not check_prime(value % self.size_table) else value % self.size_table #gt = bigger than
return next_prime_gt - (data % next_prime_gt)
def __hash_double_function(self, key, data, increment):
return (increment * self.__hash_function_2(key, data)) % self.size_table
def _colision_resolution(self, key, data=None):
i = 1
new_key = self.hash_function(data)
while self.values[new_key] is not None and self.values[new_key] != key:
new_key = self.__hash_double_function(key, data, i) if \
self.balanced_factor() >= self.lim_charge else None
if new_key is None: break
else: i += 1
return new_key

View File

@ -0,0 +1,84 @@
#!/usr/bin/env python3
from number_theory.prime_numbers import next_prime
class HashTable:
"""
Basic Hash Table example with open addressing and linear probing
"""
def __init__(self, size_table, charge_factor=None, lim_charge=None):
self.size_table = size_table
self.values = [None] * self.size_table
self.lim_charge = 0.75 if lim_charge is None else lim_charge
self.charge_factor = 1 if charge_factor is None else charge_factor
self.__aux_list = []
self._keys = {}
def keys(self):
return self._keys
def balanced_factor(self):
return sum([1 for slot in self.values
if slot is not None]) / (self.size_table * self.charge_factor)
def hash_function(self, key):
return key % self.size_table
def _step_by_step(self, step_ord):
print("step {0}".format(step_ord))
print([i for i in range(len(self.values))])
print(self.values)
def bulk_insert(self, values):
i = 1
self.__aux_list = values
for value in values:
self.insert_data(value)
self._step_by_step(i)
i += 1
def _set_value(self, key, data):
self.values[key] = data
self._keys[key] = data
def _colision_resolution(self, key, data=None):
new_key = self.hash_function(key + 1)
while self.values[new_key] is not None \
and self.values[new_key] != key:
if self.values.count(None) > 0:
new_key = self.hash_function(new_key + 1)
else:
new_key = None
break
return new_key
def rehashing(self):
survivor_values = [value for value in self.values if value is not None]
self.size_table = next_prime(self.size_table, factor=2)
self._keys.clear()
self.values = [None] * self.size_table #hell's pointers D: don't DRY ;/
map(self.insert_data, survivor_values)
def insert_data(self, data):
key = self.hash_function(data)
if self.values[key] is None:
self._set_value(key, data)
elif self.values[key] == data:
pass
else:
colision_resolution = self._colision_resolution(key, data)
if colision_resolution is not None:
self._set_value(colision_resolution, data)
else:
self.rehashing()
self.insert_data(data)

View File

@ -0,0 +1,24 @@
from .hash_table import HashTable
from collections import deque
class HashTableWithLinkedList(HashTable):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
def _set_value(self, key, data):
self.values[key] = deque([]) if self.values[key] is None else self.values[key]
self.values[key].appendleft(data)
self._keys[key] = self.values[key]
def balanced_factor(self):
return sum([self.charge_factor - len(slot) for slot in self.values])\
/ self.size_table * self.charge_factor
def _colision_resolution(self, key, data=None):
if not (len(self.values[key]) == self.charge_factor
and self.values.count(None) == 0):
return key
return super()._colision_resolution(key, data)

View File

@ -0,0 +1,29 @@
#!/usr/bin/env python3
"""
module to operations with prime numbers
"""
def check_prime(number):
"""
it's not the best solution
"""
special_non_primes = [0,1,2]
if number in special_non_primes[:2]:
return 2
elif number == special_non_primes[-1]:
return 3
return all([number % i for i in range(2, number)])
def next_prime(value, factor=1, **kwargs):
value = factor * value
first_value_val = value
while not check_prime(value):
value += 1 if not ("desc" in kwargs.keys() and kwargs["desc"] is True) else -1
if value == first_value_val:
return next_prime(value + 1, **kwargs)
return value

View File

@ -0,0 +1,26 @@
#!/usr/bin/env python3
from .hash_table import HashTable
class QuadraticProbing(HashTable):
"""
Basic Hash Table example with open addressing using Quadratic Probing
"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
def _colision_resolution(self, key, data=None):
i = 1
new_key = self.hash_function(key + i*i)
while self.values[new_key] is not None \
and self.values[new_key] != key:
i += 1
new_key = self.hash_function(key + i*i) if not \
self.balanced_factor() >= self.lim_charge else None
if new_key is None:
break
return new_key