Независимо от того, что Вы делаете не, вводят огромный код на первый ответ ! Это полностью разрушило мой экран входа в систему.
Просто использование killall pulseaudio
в терминале.
Хеширование Zobrist может вам помочь. Вам нужно создать матрицу NxN случайных целых чисел, каждая ячейка, представляющая этот элемент i, находится в j-й позиции в текущей перестановке. Для данной перестановки вы выбираете значения N ячеек и xor их один за другим, чтобы получить ключ перестановки (обратите внимание, что уникальность ключа не гарантируется).
Суть этого алгоритма в том, что если вы переключаетесь на элементы в вашем перестановок, вы можете легко сгенерировать новый ключ из текущей перестановки, просто вычеркнув старый и вставив в новые позиции.
Судя по вашему вопросу и оставленным вами комментариям, я бы сказал, что вашу проблему невозможно решить.
Позвольте мне объяснить.
Вы говорите, что вам нужен уникальный хэш из вашей комбинации, поэтому давайте сделаем это правило №1:
Хорошо, тогда в комментарии вы сказали, что, поскольку вы используете довольно много чисел, хранить их в виде строки или еще чего-то в качестве ключа к хеш-таблице невозможно, из-за ограничений памяти. Итак, давайте перепишем это в другое правило:
По сути, вы пытаетесь взять большое число и сохранить его в гораздо меньший диапазон чисел и по-прежнему имеют уникальность.
Извините, но вы не можете этого сделать.
Типичные алгоритмы хеширования производят относительно уникальные хеш-значения, поэтому, если вы не хотите принимать коллизии в том смысле, что новая комбинация может быть помечена как "уже увиденная", даже если это не так, тогда вам не повезло.
Если бы вы попробовали битовое поле, где каждая комбинация имеет бит, который равен 0 если это не было замечено, вам все равно понадобится большой объем памяти.
Для перестановки в n = 20, которую вы оставили в комментарии, у вас есть 20! (2,432,902,008,176,640,
Как предлагали другие, вы можете использовать хеширование для генерации целого числа, которое будет уникальным с высокой вероятностью. Однако, если вам нужно, чтобы целое число всегда было уникальным, вам следует ранжировать перестановки, то есть назначить им порядок. Например, обычным порядком перестановок для набора {1,2,3} является лексикографический порядок:
В этом случае id перестановки является ее индексом в лексикографическом порядке. Конечно, есть и другие методы ранжирования перестановок.
Создание идентификаторов в виде диапазона непрерывных целых чисел позволяет реализовать хранение обработанных перестановок в виде битового поля или логического массива.
Насколько быстро это должно быть?
Вы всегда можете собрать целые числа в виде строки, затем взять хэш этого числа, а затем просто взять первые 4 байта.
Для хеша вы действительно можете использовать любую функцию, например MD5 или SHA-256.
Вы можете MD5 хешировать строку, разделенную запятыми, содержащую ваши int.
В C # это будет выглядеть примерно так (Отказ от ответственности: у меня есть на машине, которую я использую сегодня, нет компилятора):
using System;
using System.Security.Cryptography;
using System.Text;
public class SomeClass {
static Guid GetHash(int[] numbers) {
string csv = string.Join(',', numbers);
return new Guid(new MD5CryptoServiceProvider().ComputeHash(Encoding.ASCII.GetBytes(csv.Trim())));
}
}
Edit: О чем я думал? Как утверждают другие, вам не нужен хеш. CSV должно быть достаточно в качестве строкового идентификатора (если только ваш массив чисел не большой).
Не относится непосредственно к вопросу, но в качестве альтернативного решения вы можете использовать Trie tree в качестве структуры поиска. Деревья Trie очень хороши для операций со строками, их реализация относительно проста и должна быть быстрее (max n (k), где k - длина ключа), чем хеш-набор для большого количества длинных строк. И вы не ограничены в размере ключа (например, в обычном хеш-наборе в must int, а не больше). Ключом в вашем случае будет строка всех чисел, разделенных некоторым символом.
Подобно сообщению Бояна кажется, что лучший способ пойти - это установить детерминированный порядок перестановок. Если вы обрабатываете их в этом порядке, то нет необходимости выполнять поиск, чтобы увидеть, не выполнили ли вы уже какую-либо конкретную перестановку.
Простые степени будут работать: если p_i
является i -м простым числом, а a_i
является i -м элемента кортежа, то
p_0**a_0 * p_1**a_1 * ... * p_n**a_n
должен быть уникальным согласно Фундаментальной теореме арифметики . Однако эти числа станут довольно большими: -)
(например, для n = 5, (1,2,3,4,5) будет отображаться в 870 037 764 750, что уже превышает 32 бита)
Преобразуйте каждое число в строку, объедините строки (через StringBuffer) и используйте содержимое StringBuffer в качестве ключа.