Что разумное является главным для вычисления хэш-кода?

Дата возвращения [Только 112]

Select Cast(Floor(Cast(Getdate() As Float))As Datetime)

или

Select DateAdd(Day, 0, DateDiff(Day, 0, Getdate()))
57
задан Hans-Peter Störr 25 September 2017 в 13:27
поделиться

5 ответов

Я рекомендую использовать 92821 . Вот почему.

Чтобы дать осмысленный ответ на этот вопрос, вы должны кое-что знать о возможных значениях i и j . Единственное, о чем я могу думать в целом, это то, что во многих случаях маленькие значения будут более распространенными, чем большие значения. (Вероятность появления 15 в качестве значения в вашей программе намного выше, чем, скажем, 438281923.) Таким образом, кажется хорошей идеей сделать наименьшее столкновение хэш-кода как можно большим, выбрав подходящее простое число. Для 31 это довольно плохо - уже для i = -1 и j = 31 у вас есть то же хеш-значение, что и для i = 0 и j = 0 .

Поскольку это интересно, я написал небольшую программу, которая просматривала весь диапазон int в поисках лучшего простого числа в этом смысле. То есть для каждого простого числа я искал минимальное значение Math.abs (i) + Math.abs (j) по всем значениям i, j , которые имеют одинаковый хэш-код. как 0,0 , а затем взяли простое число, где это минимальное значение является как можно большим.

Барабан : лучшее простое число в этом смысле - 486187739 (с наименьшим столкновением i = -25486, j = 67194 ). Примерно так же хорошо и намного проще запомнить 92821 с наименьшим столкновением i = -46272 и j = 46016 .

Если вы придаете «малому» другое значение и хотите получить минимум Math.sqrt (i * i + j * j) для максимально возможного столкновения результаты немного отличаются: лучшим будет 1322837333 с i = -6815 и j = 70091 , но мой любимый 92821 (наименьшее столкновение -46272,46016 ) снова почти так же хорош, как и лучшее значение.

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

73
ответ дан 24 November 2019 в 19:39
поделиться

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

5
ответ дан 24 November 2019 в 19:39
поделиться

Коллизии не могут быть такой большой проблемой ... Основная цель хэша - избежать использования равенства для сравнений 1: 1. Если у вас есть реализация, в которой equals «обычно» чрезвычайно дешево для объектов, которые столкнулись с хешами, то это не проблема (вообще).

В конце концов, какой способ хеширования является лучшим, зависит от того, кто вы сравнение. В случае пары int (как в вашем примере) достаточно использовать базовые побитовые операторы (например, & или ^).

5
ответ дан 24 November 2019 в 19:39
поделиться

Вам нужно определить свой диапазон для i и j. Вы можете использовать простое число для обоих.

public int hashCode() {
   http://primes.utm.edu/curios/ ;)
   return 97654321 * i ^ 12356789 * j;
}
4
ответ дан 24 November 2019 в 19:39
поделиться

Я бы выбрал 7243. Достаточно большой, чтобы избежать столкновений с маленькими числами. Не переполняется быстро до малых чисел.

3
ответ дан 24 November 2019 в 19:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: