У меня есть числа в определенном диапазоне (обычно от 0 до 1000). Алгоритм выбирает некоторые числа из этого диапазона (от 3 до 10 чисел). Этот выбор выполняется довольно часто, и мне нужно проверить, была ли выбрана перестановка выбранных номеров.
например, один шаг выбирает [1, 10, 3, 18]
и еще один [10, 18, 3, 1]
, тогда второй выбор может быть отброшен, потому что это перестановка.
Мне нужно сделать эту проверку очень быстро. Прямо сейчас я помещаю все массивы в хэш-карту и использую пользовательскую хеш-функцию: просто суммируем все элементы, поэтому 1 + 10 + 3 + 18 = 32, а также 10 + 18 + 3 + 1 = 32. Для равных я использую битрейт, чтобы быстро проверить, находятся ли элементы в обоих наборах (мне не нужна сортировка при использовании битового набора, но она работает только тогда, когда диапазон чисел известен и не слишком большой).
Это работает нормально, но может генерировать много коллизий, поэтому метод equals() вызывается довольно часто. Мне было интересно, есть ли более быстрый способ проверить перестановки?
Существуют ли хорошие хеш-функции для перестановок?
UPDATE
Я сделал небольшой тест: сгенерировал все комбинации чисел в диапазоне от 0 до 6 и длину массива от 1 до 9. Есть 3003 возможных перестановки, и хороший хэш должен сгенерироваться рядом с этим множеством разных хэшей (я использую 32-битные номера для хэша):
- 41 хеши для просто добавления (так много конфликтов)
- 8 разных хэшей для значений XOR'ing вместе
- 286 различных хэшей для умножения
- Было предложено 3003 различных хэша для (R + 2e) и умножено на abc (используя 1779033703 для R)
Таким образом, abc hash может быть рассчитан очень быстро и намного лучше, чем все остальные. Спасибо!
PS: Я не хочу сортировать значения, когда мне это не нужно, потому что это будет слишком медленным.