Hash Table
Представьте крупный веб-сайт электронной коммерции, на котором отображаются списки товаров, подгружаемые из базы данных. При каждом посещении сайта серверу приходится запрашивать этот список товаров из базы данных, что требует времени и ресурсов сервера.
Для решения этой проблемы часто используется система кэширования. При запросе пользователем страницы с перечнем товаров, система первым делом проверяет наличие запрошенной страницы в кэше. Для быстродействия кэширование реализовано в виде хэш-таблицы, где URL страницы служит ключом (key), а список товаров - значением(value).
Рассмотрим, что же собой представляет хэш-таблица - это структура данных, которая использует хэш функцию для перевода ключа(в нашем случае URL страницы) в индекс.
Когда у нас есть индекс для URL, мы можем обратиться к массиву по этому индексу и получить значение или установить новое. Таким образом, вместо поиска нужной страницы и связанного с ней списка товаров, что занимает время O(n), мы получаем доступ к списку товаров за O(1).
К хэш функции предъявляются следующие требования:
одинаковые входные данные должны давать один и тот же индекс (в примере page1 всегда соотвествует 5)
хэш-функция может возвращать одинаковые значения для разных входных данных, но при этом чем меньше таких случаев тем лучше (хэш функция, которая всегда будет возвращать 1 - плохая, так как вызовет много коллизий)
Пример хэш-функции для строк, созданная в 1991 году Daniel J. Berstein:
|
|
Коллизии - это явление в хэшировании, когда разные входные данные дают одинаковое значение хэша.
Чтобы решить проблему коллизий, существуют разные методы, включая открытое хэширование (Open Hashing значение массива становится списком, в нашем примере index 5 -> [список товаров page1, список товаров page7]) и закрытое хэширование (Closed Hashing). Открытое хэширование позволяет хранить несколько значений по одному индексу, в то время как закрытое хэширование пытается найти новый индекс для данных, вызывающих коллизию.
Hовый индекс Closed Hashing может быть получен следующим способом:
- линейным(Linear Probing),
- квадратичным(Quadratic Probing),
- двойным хэшированием (Double hashing)
Python предоставляет реализацию хэш-таблицы в виде словаря (dict), который хранит пары key-value. Чтобы объект мог быть использован в качестве key в словаре, он должен поддерживать хэш-функцию (через метод __hash__
), а также операцию сравнения на равенство (через методы __eq__
или __cmp__
).
Важно отметить, что метод __eq__
используется при разрешении коллизий для нахождения правильного значения.
Одной из частых ошибок среди новичков является попытка использования list в качестве key. Однако стоит помнить, что list может менять количество элементов и их значения. В результате, создание надежных функций __hash__
и __eq__
для list затруднительно.
Код ниже вернет ошибку: TypeError: unhashable type: ’list'
|
|