2009-04-09 6 views
10

Область интересов - соответствие строк. Предположим, у меня есть такая структура.Как бы вы хотели спроектировать функцию для идеального хэша?

typedef struct 
{ 
    char *name, 
    int (*function)(); 

} StringArray 

StringArray s[] = 
{ 
    {"George", func1}, 
    {"Paul", func2}, 
    {"Ringo", func3}, 
    {"John", func4}, 
    {"",  NULL} /* End of list */ 
} 

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

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

Какие у вас идеи по созданию функции для этого?

+0

Я не думаю, что спам означает, что вы думаете, что значит –

+0

@Mitch: Вы имеете в виду, что это вопрос, который может быть легко гугле для? –

+0

@ j_random_hacker: Я сделал. Но уже поздно, и это не спам ... –

ответ

16

Смотрите gperf домашнюю страницу.

+0

Отвратительная часть состоит в том, что есть ссылка на это в нижней части страницы википедии. – EvilTeach

0

Вы можете воспользоваться картой

std::string foo() { return "Foo"; } 
std::string bar() { return "Bar"; } 

int main() 
{ 
    std::map<std::string, std::string (*)()> m; 
    m["foo"] = &foo; 
    m["bar"] = &bar; 
} 
+0

std :: карта не использует хэш - это основано на дереве – 2009-04-09 15:37:18

+0

зачем изобретать колесо, вы можете использовать существующие библиотеки, такие как map. – Vinay

+1

, возможно, интересующемуся игроку нужны характеристики хэширования, а не поиска дерева? – 2009-04-09 15:43:23

1
+0

Не затрагивает вопрос напрямую, но хорошие ссылки в любом случае. – EvilTeach

+0

Будет ли downvoter (на этот очень старый вопрос), пожалуйста, оставьте комментарий. Благодарю. –

0

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

Что бы я сделал, это применить один из существующих общих сильных алгоритмов хеширования, таких как: MD5 или SHA. Здесь есть мириады образцов, вот один пример: http://www.codeproject.com/KB/security/cryptest.aspx

-1

Ну, нет идеальной хэш-функции.

У вас есть несколько, которые минимизируют столкновения, но ни одна из них не устраняет их.

Не могу посоветовать одно, хотя: P

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

+0

http://en.wikipedia.org/wiki/Perfect_hashing –

+0

@Adam: Там есть довольно большой оговоркой, учитывая, что он применяется только в том случае, если существует отдельный набор данных. Поскольку ОП не упоминал об ограничении использования строк, я бы согласился с Megacan, что в этом случае нет идеального хэша. +1. – sipwiz

+0

Вопроситель действительно упоминает, по крайней мере, неявно - было только четыре битла) или siz, если вы включили барабанщика, которого они уволили, и Stu whatsisname) - все еще фиксированный набор данных. – 2009-04-09 15:52:27

0

Использование сбалансированного двоичного дерева. Тогда вы KNOW поведение ВСЕГДА O (logn).

Мне сильно не нравятся хеши. Люди не понимают, сколько рисков они берут с помощью своего алгоритма. Они запускают некоторые тестовые данные, а затем развертывают их в полевых условиях. Я НИКОГДА не видел, чтобы развернутый хэш-алгоритм проверялся на поведение в поле.

O (log n) почти всегда приемлемо вместо O (1).

+0

«O (log n) почти всегда приемлемо вместо O (1)». Во многих приложениях это утверждение неверно. Просто увеличьте количество точек данных до нескольких миллионов, чтобы это увидеть. –

+0

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

+0

В этом случае все входы известны. Они сидят в массиве. , а строка ввода - либо точное совпадение, либо несоответствие. – EvilTeach

2

В сводке перечислены как C, так и C++. Какие из них вы ищете? C и C++ - это два разных языка и сильно различаются в строковой обработке и структурах данных (и тот факт, что C-работы, работающие на C++, не меняют этого).

Почему именно вам нужна идеальная хэш-функция? Это то, что вы хотите связать строку с функцией, и подумал, что это будет хороший способ сделать это? Это какое-то домашнее задание? У вас есть причина не использовать карту <> в C++? (Или unordered_map <> если доступно?)

Если вам нужен идеальный хеш, каковы ограничения на строки? Будет ли определенный фиксированный набор, на который вы хотите отправить? Что относительно строк, которые не соответствуют одному из наборов? Готовы ли вы принимать хиты из случайных строк, или количество входящих строк ограничено?

Если бы вы могли отредактировать свой вопрос, включив такую ​​информацию, мы могли бы быть намного полезнее.

EDIT (в ответ на первые два комментария):

ОК, мы должны смотреть на решения C, так как вы хотите, чтобы это предположительно как для вашей C и C++ работы. Вы, по-видимому, хотите исполнения, но вы протестировали? Если мы имеем дело со строками, входящими в систему ввода-вывода, время, которое, вероятно, затмит время отправки.

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

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

+0

Я код в c и C++, и бог помогите мне Pro * C. O (1) хеширование для производительности. Lol, без задания домашней работы. Я ищу, чтобы создать инструмент для ускорения некоторых критически важных показателей. Пример упрощен для обсуждения. Реального мира нет. – EvilTeach

+0

Строки будут очень длинными. Ни один из них не будет иметь нулевой длины. Как практическое ограничение, никакая строка в массиве не будет длиннее 32 символов. То, что проходит вызывающий, может быть любой длины, но если оно длиннее строк в таблице, это случай отсутствия соответствия – EvilTeach

+0

+1 для упоминания trie. –

0

Конечный результат этого упражнения было

  • Украсть число строк ориентированных хэш-функций от сети.
  • Создайте своего рода заводской класс, который проверял каждую из функций против набора данных с диапазоном значений оператора мод, ища наименьший совершенный хеш, который работает с этой функцией.
  • Этот конструктор по умолчанию фабричного класса возвращает строку, представляющую набор аргументов, которые при использовании выбирают правильную хеш-функцию и размер мода, чтобы дать идеальный хэш, требующий наименьшего объема памяти.
  • При нормальном использовании вы просто создаете экземпляр класса с возвращаемыми аргументами, а класс ставит себя в рабочее состояние с нужными функциями.
  • Этот конструктор проверяет, нет ли столкновений и прерываний, если они есть.
  • В случае отсутствия идеального хэша он деградирует в двоичный поиск по отсортированной версии таблицы ввода.

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

Благодарю всех, кто внес идеи.

Зла