Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Поиск информации с помощью хэш-таблиц, Хэш-функции для быстрого поиска данных 
:(
    Опции темы
Voldemar2004
  Дата 27.5.2007, 21:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1650
Регистрация: 25.12.2004

Репутация: нет
Всего: 23



Как можно с помощью хэш-таблиц (и хэш-функции) получить быстрый доступ к данным ? Например, у меня такая задача: цепное хэширование - информация - это структура вида: "Номер, Ф.И.О." хэширование идет по полю 'Номер'.

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

На форуме нашел очень мало инфы про хэш. smile 


--------------------
i_i 
(';') 
(V)

user posted image
PM MAIL   Вверх
MAKCim
Дата 27.5.2007, 21:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата

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

вот код получения хэш-кода от строки (из ядра Linux)
Код

#define init_name_hash()                0

Код

static inline unsigned long
partial_name_hash(unsigned long c, unsigned long prevhash) {
    return (prevhash + (c << 4) + (c >> 4)) * 11;
}

Код

unsigned int c;
c = *(const unsigned char *)name;
hash = init_name_hash();
do {
    name++;
    hash = partial_name_hash(c, hash);
    c = *(const unsigned char *)name;
} while (c);
Цитата




Это сообщение отредактировал(а) MAKCim - 27.5.2007, 21:14


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
zkv
Дата 27.5.2007, 23:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Участник Клуба
Сообщений: 2133
Регистрация: 23.7.2006
Где: Санкт-Петербург

Репутация: 26
Всего: 92



На пальцах:
Пример 1. 
Есть таблица типа 
Цитата

0 "нуль"
1 "один"
2 "два"
3 "три"

нам необходимо по по числовому значению получать соответствующую строку, тут не надо изобретать велосипедов, просто заводим массив строк -> обращение по индексу равному нужному нам числовому значению дает нужную строку. Быстродействие максимальное, больше ничего не придумаешь, хешировать тут нечего. 

Пример 2. 
Таблица вида:
Код

"zero" "нуль"
"one" "один"
"two" "два"
"three" "три"

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

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

Очевидно, что невозможно реализовать хеш-функцию, дающую уникальный код для каждого значения (конечно если множество возможных значений больше чем множество возможных хеш-кодов). 
Случай, когда функция выдает один и тот же хеш код для разных значений называется коллизией. 
Понятно, что чем больше будет коллизий тем ниже эффективность. Колличество коллизий будет зависеть как от качества самой функции, так и от размера хеш-таблицы.
Хеш таблица - это таблица с хешированными данными, она заранее делается большего размера, чем нужно фактически, опять таки для уменьшения колличества коллизий. 
Сначала эту таблицу необходимо создать, для этого данные хешируются и в эту таблицу размещаются, в нашем случае получится что то типа этого (пусть таблица будет в два раза больше чем нам реально требуется, к сожалению совсем не помню какие цифры должны быть в реальности, вроде есть какие то рекомендации к размеру):
Цитата

"two" "два"   //0
<пусто>       //1
<пусто>       //2
"zero" "нуль"//3
<пусто>       //4
"one" "один" //5
"three" "три" //6
<пусто>        //7

Понятно, что реальное расположение элементов будет зависеть от хеш-функции. 
В этом случае заполнение происходило так: 
для строки "zero" функция выдала хеш-код == 3 => проверяем, есть ли кто нить уже на этой позиции - нет, тогда заносим этот элемент в хеш-таблицу в соответствующую позицию.
для строки "one" получили 5 -> проверили -> занесли
для строки "two" получили 0 -> проверили -> занесли
для строки "three" возможны два варианта, либо мы получили 6, и сразу занесли запись на место, либо получили 5 и вышла коллизия, рассмотрим последний вариант.  получили 5 -> проверили - блин, занято, ну фиг с ним посмотрим на следующую ячейку - ага свободно, ну пусть тут и живет smile 

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

Пробуем найти "three", по адресу полученному хеш-функцией лежит что то левое, не беда, вспоминаем, что мы делали, в случае коллизии? Ага смотрели на следующий, поступим также, те перебором ищем наш элемент, он должен быть где-то рядом smile 

Что то про конкретные реализации есть в википедии, да в инете их вагон должен быть.
Удачи!

Это сообщение отредактировал(а) zkv - 27.5.2007, 23:28
PM MAIL   Вверх
v_nikolaev
Дата 28.5.2007, 08:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 38
Регистрация: 6.5.2007

Репутация: нет
Всего: нет



Цитата(Voldemar2004 @ 27.5.2007,  21:07)
Как можно с помощью хэш-таблиц (и хэш-функции) получить быстрый доступ к данным ? Например, у меня такая задача: цепное хэширование - информация - это структура вида: "Номер, Ф.И.О." хэширование идет по полю 'Номер'.

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

На форуме нашел очень мало инфы про хэш. smile

Суть такая.

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

Таким образом, если у нас есть некоторое значение, мы преобразуем его в индекс и смотрим по этому индексу, есть ли уже такое в массиве или нет.
Индекс, разумеется может повторяться для разных значений, важно, чтобы подряд идущие значения получали сильно разные индексы - в этом суть "перемалывания".

Когда у двух значений, которые мы собираемся хранить совпадают индексы (происходит так называемая коллизия), их приходится помещать в списочек для данного индекса. Чем больше таких коллизий, тем хуже время доступа к элементам таблицы в среднем.
PM MAIL   Вверх
korbian
Дата 28.5.2007, 08:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 336
Регистрация: 20.2.2007
Где: Penza

Репутация: 2
Всего: 14



Посмотри также 
Код

stdext::hash_map
stdext::hash_multimap
stdext::hash_set
stdext::hash_multiset

Хоть и не стандарт, но в STLport есть и с MS VC++ 7.1 помоему тоже уже есть.


--------------------
korbian ©
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0471 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.