Поскольку вы знаете все строки заранее, вы можете использовать gperf для генерации совершенной хеш-функции , в которой нет коллизий. Например, с четырьмя входными строками AAAA ABBA ACEA ALFG
он сгенерировал следующую хеш-функцию (используя командную строку gperf -L ANSI-C input.txt
):
static unsigned int
hash (register const char *str, register unsigned int len)
{
static unsigned char asso_values[] =
{
12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 7, 2, 5, 12, 12,
12, 12, 12, 12, 12, 12, 0, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12
};
return len + asso_values[(unsigned char)str[1]];
}
const char *
in_word_set (register const char *str, register unsigned int len)
{
static const char * wordlist[] =
{
"", "", "", "",
"ALFG",
"",
"ABBA",
"", "",
"ACEA",
"",
"AAAA"
};
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
{
register int key = hash (str, len);
if (key <= MAX_HASH_VALUE && key >= 0)
{
register const char *s = wordlist[key];
if (*str == *s && !strcmp (str + 1, s + 1))
return s;
}
}
return 0;
}
Для чего требуется поиск по одной таблице, сравнение длины и сравнение строк. Если вы точно знаете, что слово, которое вы хэшируете, является одним из ваших исходных слов, тогда вы можете пропустить сравнение строк.
Увеличение входного размера с 4 до 10000 случайно сгенерированных строк увеличивает хеш-функцию до 4-х просмотров таблиц плюс сравнение длины и сравнение строк. Но, поскольку при сравнении строк необходимо хранить каждую исходную строку, это приводит к очень большой таблице в скомпилированном объектном файле (1,4 МБ). Если вам не нужно сравнивать строки, вы можете опустить эту таблицу.