КулЛиб - Классная библиотека! Скачать книги бесплатно
Всего книг - 803447 томов
Объем библиотеки - 2093 Гб.
Всего авторов - 303857
Пользователей - 130336

Впечатления

Влад и мир про Энсвер: Повелитель земли (Фэнтези: прочее)

Я читал у автора другие книги и они мне нравились, но это увы. ГГ у автора дебил и рукожопый.Рассуждения соответствующие. Лук автору трудно сделать. Найти упругую ветку? Всё отрицает, считая, что надо учиться стрелять и метать камни годами. Что бы чему то научится, надо пробовать и получать опыт. А там как маторика. Кто то и с 3 раза попадать сможет, а кому то и тысячи повторов мало. Автор заставляет для изготовления ножа искать на берегу

  подробнее ...

Рейтинг: 0 ( 0 за, 0 против)
Autumn E про Берг: Отвергнутая целительница для Дракона (Любовная фантастика)

Прочитать это можно, но удовольствия от этой сказки мало. Герои противные и у них сплошные проблемы во всём и со всеми, некрасивая и глуповатая сказка о дурости. Наличие магии таким героям только во вред, авторша постаралась изобразить горе от "ума", хотя мне кажется у нее была другая задумка, но тут уж как вышло!

Рейтинг: 0 ( 0 за, 0 против)
Autumn E про Берг: Сбежать от истинного. (Не)Желанная невеста (Любовная фантастика)

Няшка дурашка и злобный хрен, пардон дракон, резко передумавший быть злобным. Можно попытаться это погрызть, если совсем нечего читать.

Рейтинг: 0 ( 0 за, 0 против)
banza про Горъ: Полукровка 3 (Боевая фантастика)

Уважаемый Автор файла: Цокольный этаж. Огромная просьба, не отходите от замечательной традиции Горъ-овские файлы выкладывать в двух видах: с иллюстрациями и без. Это вот ну прям здорово вы делаете...

Рейтинг: +1 ( 1 за, 0 против)
pva2408 про Пламенев: Миротворец II. Дипломатия Мечей (Городское фэнтези)

Предыдущий первый том: https://coollib.in/b/796158-vladimir-plamenev-diplomatiya-klanov автор на АТ скрыл. Как первый том ( с таким названием) выложен у него на странице в АТ: https://author.today/work/series/46755

Рейтинг: 0 ( 0 за, 0 против)

Хеш-таблицы [Иван Кисляков Программист] (fb2) читать постранично


 [Настройки текста]  [Cбросить фильтры]

Иван Кисляков ХЕШ-ТАБЛИЦЫ

Предисловие

Я много раз заглядывал на просторы интернета, нашел много интересных статей о хеш-таблицах, но вразумительного и полного описания того, как они реализованы, так и не нашел. В связи с этим мне просто не терпелось написать пост на данную, столь интересную, тему.

Возможно, она не столь полезна для опытных программистов, но будет интересна для студентов технических ВУЗов и начинающих программистов-самоучек.

Мотивация использовать хеш-таблицы

Для наглядности рассмотрим стандартные контейнеры и асимптотику их наиболее часто используемых методов.


Контейнер \ операция insert remove find Array O(N) O(N) O(N) List O(1) O(1) O(N) Sorted array O(N) O(N) O(logN) Бинарное дерево поиска O(logN) O(logN) O(logN) Хеш-таблица O(1) O(1) O(1) Все данные при условии хорошо выполненных контейнерах, хорошо подобранных хеш-функциях


Из этой таблицы очень хорошо понятно, почему же стоит использовать хеш-таблицы. Но тогда возникает противоположный вопрос: почему же тогда ими не пользуются постоянно?

Ответ очень прост: как и всегда, невозможно получить все сразу, а именно: и скорость, и память. Хеш-таблицы тяжеловесные, и, хоть они и быстро отвечают на вопросы основных операций, пользоваться ими все время очень затратно.

Понятие хеш-таблицы

Хеш-таблица — это контейнер, который используют, если хотят быстро выполнять операции вставки/удаления/нахождения. В языке C++ хеш-таблицы скрываются под флагом unordered_set и unordered_map. В Python вы можете использовать стандартную коллекцию set — это тоже хеш-таблица.

Реализация у нее, возможно, и не очевидная, но довольно простая, а главное — как же круто использовать хеш-таблицы, а для этого лучше научиться, как они устроены.

Для начала объяснение в нескольких словах. Мы определяем функцию хеширования, которая по каждому входящему элементу будет определять натуральное число. А уже дальше по этому натуральному числу мы будем класть элемент в (допустим) массив. Тогда имея такую функцию мы можем за O(1) обработать элемент.

Теперь стало понятно, почему же это именно хеш-таблица.

Проблема коллизии

Естественно, возникает вопрос, почему невозможно такое, что мы попадем дважды в одну ячейку массива, ведь представить функцию, которая ставит в сравнение каждому элементу совершенно различные натуральные числа просто невозможно. Именно так возникает проблема коллизии, или проблемы, когда хеш-функция выдает одинаковое натуральное число для разных элементов.

Существует несколько решений данной проблемы: метод цепочек и метод двойного хеширования. В данной статье я постараюсь рассказать о втором методе, как о более красивом и, возможно, более сложном.

Решения проблемы коллизии методом двойного хеширования

Мы будем (как несложно догадаться из названия) использовать две хеш-функции, возвращающие взаимопростые натуральные числа.

Одна хеш-функция (при входе g) будет возвращать натуральное число s, которое будет для нас начальным. То есть первое, что мы сделаем, попробуем поставить элемент g на позицию s в нашем массиве. Но что, если это место уже занято? Именно здесь нам пригодится вторая хеш-функция, которая будет возвращать t — шаг, с которым мы будем в дальнейшем искать место, куда бы поставить элемент g.

Мы будем рассматривать сначала элемент s, потом s + t, затем s + 2*t и т.д. Естественно, чтобы не выйти за границы массива, мы обязаны смотреть на номер элемента по модулю (остатку от деления на размер массива).

Наконец мы объяснили все самые важные моменты, можно перейти к непосредственному написанию кода, где уже можно будет рассмотреть все оставшиеся нюансы. Ну а строгое математическое доказательство корректности использования двойного хеширования можно найти тут.

Реализация хеш-таблицы

Для наглядности будем реализовывать хеш-таблицу, хранящую строки.

Начнем с определения самих хеш-функций, реализуем их методом Горнера. Важным параметром корректности хеш-функции является то, что возвращаемое значение должно быть взаимопросто с размером таблицы. Для уменьшения дублирования кода, будем использовать две структуры, ссылающиеся на реализацию самой хеш-функции.


int HashFunctionHorner(const std::string& s, int table_size, const int key)

{

    int hash_result = 0;

    for (int i = 0; s[i] != s.size(); ++i)

        hash_result = (key * hash_result + s[i]) % table_size;

    hash_result = (hash_result * 2 + 1) % table_size;

    return hash_result;

}

struct HashFunction1

{

    int operator()(const std::string& s, int table_size) const

    {

        return HashFunctionHorner(s, table_size, table_size - 1);

        // ключи должны быть взаимопросты, используем числа

        // <размер таблицы> плюс и минус один.

    }

};

--">