Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   Сверхбыстрый поиск (http://forum.oszone.net/showthread.php?t=168424)

ManHack 24-02-2010 18:36 1355025

Сверхбыстрый поиск
 
Добрый вечер!
Мне нужно реализовать очень быстрый поиск в маленькой таблице из сорока элементов.
Поиск по таблице будет прогоняться десятки-сотни тысяч раз подряд, поэтому нужен быстрый алгоритм.
Пораскинув мозгами я пришёл к выводу, что без хэш-таблицы тут не обойтись... (к правильному выводу пришёл я?)
Каков наиболее быстрый алгоритм поиска в хэш-таблице? Что мне использовать?
Или же есть что-то, работающее быстрее в данной ситуации, чем хэш-поиск.

Таблица фиксированная, в процессе поиска меняться не будет, её можно изначально упорядочить наиболее удобным образом (рекомендации?).

lxa85 24-02-2010 20:52 1355106

Цитата:

Цитата ManHack
рекомендации? »

Зависят от типа данных по которому идет поиск.
Приведи пример записи таблицы.

ManHack 25-02-2010 17:54 1355814

В таблице два поля: строка и множество (паскалевский перечислимый тип).
Т.е. одна запись таблицы выглядит, например, так:
DEFENITION | ccDef
где DEFENITION - строка - ключ, по которой ведётся поиска, а ccDef - элемент множетства ( ccDef, ccTor, {...} , ccAss, ccOp ) - данные, которые мы ищем по ключу.

ganselo 25-02-2010 19:27 1355876

ManHack, думаю хэшь стоит использовать если строки большого размера.

ManHack 26-02-2010 01:04 1356140

Строки маленькие, до десяти символов.
Что можно сделать, чтобы не возникало коллизий?

ganselo, а раз не хэш, тогда что? что будет работать быстрее поиска по хэш-таблице в такой ситуации?

pva 28-02-2010 00:02 1357765

кажись только хеш по самому различаемому (из 40 статичных строчек) символу + длина строчки (если различается)

Busla 03-03-2010 11:47 1360214

Цитата:

Цитата ManHack
Пораскинув мозгами я пришёл к выводу, что без хэш-таблицы тут не обойтись... (к правильному выводу пришёл я?) »

Как вы связываете зрение и слух - Если уши отрезать, папаха на глаза упадёт ;-)
По хэшу тоже надо как-то искать - т.е. это не ответ на вопрос об алгоритме поиска. Тем более, хэш надо вычислять на каждом шаге. Есть большое подозрение, что на таком небольшом количестве данных тупой перебор со сравненим окажется самым выгодным.

ManHack 04-03-2010 23:23 1361451

Нужно придумать идеальную хеш-функцию для слов ARRAY, BY, BEGIN, CASE далее по списку (чтобы значения хеш-функции для различных слов из списка не совпадали)
Цитата:

EnterKW('ARRAY', lexNone);
EnterKW('BY', lexNone);
EnterKW('BEGIN', lexBEGIN);
EnterKW('CASE', lexNone);
EnterKW('CONST', lexCONST);
EnterKW('DIV', lexDIV);
EnterKW('DO', lexDO);
EnterKW('ELSE', lexELSE);
EnterKW('ELSIF', lexELSIF);
EnterKW('END', lexEND);
EnterKW('EXIT', lexNone);
EnterKW('FOR', lexNone);
EnterKW('IF', lexIF);
EnterKW('IMPORT', lexIMPORT);
EnterKW('IN', lexNone);
EnterKW('IS', lexNone);
EnterKW('LOOP', lexNone);
EnterKW('MOD', lexMOD);
EnterKW('MODULE', lexMODULE);
EnterKW('NIL', lexNone);
EnterKW('OF', lexNone);
EnterKW('OR', lexNone);
EnterKW('POINTER', lexNone);
EnterKW('PROCEDURE', lexNone);
EnterKW('RECORD', lexNone);
EnterKW('REPEAT', lexNone);
EnterKW('RETURN', lexNone);
EnterKW('THEN', lexTHEN);
EnterKW('TO', lexNone);
EnterKW('TYPE', lexNone);
EnterKW('UNTIL', lexNone);
EnterKW('VAR', lexVAR);
EnterKW('WHILE', lexWHILE);
EnterKW('WITH', lexNone);
Я придумал так:
for i := 1 to length (Stroka) do
result := result + Stroka[i]*31; (символы строки складываются и каждый раз домножается на 31)
hash := result mod SizeOfHashTable;

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

Как использовать повторное хеширование?

pva 05-03-2010 07:56 1361550

ИМХО первая буква XOR вторая
а сочетание {первая, втроая, последняя} - вобще уникальное

ManHack 06-03-2010 12:33 1362283

Цитата:

Цитата pva
ИМХО первая буква XOR вторая
а сочетание {первая, втроая, последняя} - вобще уникальное »

первая XOR вторая - не подходит, т.к. REPEAT и RECORD, например.
первая XOR последняя, первая XOR вторая XOR последняя, длина слова XOR первая XOR последняя, длина слова XOR вторая XOR последняя, XOR всех букв - все они дают коллизии на данном множестве из 34 слов.
Пишу так:
Код:

hash := ord(Name[1]) XOR ord(Name[length(Name)]);
Какие ещё будут идеи?

luna2005 06-03-2010 15:33 1362358

Пишется под 32-разрядный процессор?

Тогда первые 4 байта сравнивать без всяких хешей, к коротким словам естественно перед этим добавить нули/пробелы.

Если известно какие слова будут попадаться чаще, их поместить в начало таблицы.

pva 06-03-2010 22:22 1362596

без xor, сочетание {первая, вторая, последняя} - хотя в один байт это не упихать

ManHack 09-03-2010 23:12 1364815

Сделал так:
Код:

hash := ord(Name[1])*100 + ord(Name[length(Name)]) - 6588;
(коды заглавных латинских букв заведомо двузначные)

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

pva 10-03-2010 07:45 1364990

Цитата:

Цитата ManHack
(коды заглавных латинских букв заведомо двузначные) »

их 26 штук, попробуй * 26


Время: 12:37.

Время: 12:37.
© OSzone.net 2001-