Я не уверен, что лучший способ сделать хэширование "словаря" в таблицу.
Словарь имеет 61406 слов, я определяю перегрузку по SizeOFDictionary/.75
Это дает мне 81874 ведра в таблице.
Я запускаю его через хэш-функцию (общий случайный алгоритм), и есть 31690 ведер, которые истощаются. и 50 тысяч, которые пусты. Самое большое ведро содержит только 10 слов.
Мой вопрос: достаточны ли эти числа для проекта хэширования? Я не знаком с тем, чего я пытаюсь достичь, мне кажется, что около 50 тысяч - это много пустых ведер.
Вот моя функция хэширования.
private void hashingAlgorithm(String word)
{
int key = 1;
//Multiplying ASCII values of string
//To determine the index
for(int i = 0 ; i < word.length(); i++){
key *= (int)word.charAt(i);
//Accounting for integer overflow
if(key<0)
key*=-1;
}
key %= sizeOfTable;
//Inserting into the table
table[key].addToBucket(word);
}
Анализ производительности:
Функция хеширования не учитывает порядок. Согласно вашему алгоритму, если нет переполнения, ab = ba
. Ваш код зависит от переполнения, чтобы различать другой порядок. Таким образом, есть место для большого количества дополнительных коллизий, которые можно удалить, если вы думаете, что предложения являются номером на основе N.
Предлагаемое улучшение:
2 * 3 == 3 * 2
но 2 * 223 + 3 != 3 * 223 + 2
Поэтому, если мы представляем строки как число на основе N, количество столкновений будет уменьшаться в значительном масштабе.
Если словарь содержит слова типа:
abdc
abcd
dbca
dabc
dacb
все будут хэшироваться до одного значения в хэш-таблице, т.е. int(a)*int(b)*int(c)*int(d)
, что не является хорошей идеей.
Итак, используйте хеш.
пример: hash = [0]*base^(n-1) + [1]*base^(n-2) +... + [n-1]
где base - prime number
например 31
.
ПРИМЕЧАНИЕ: [i]
означает char.at(i)
.
вы также можете использовать оператор modulo p
[очевидно, p - простое число], чтобы избежать overflow
и ограничить size
хэш-таблицы.
hash = [0]*base^(n-1) + [1]*base^(n-2) +... + [n-1] mod p