Генерация идентификаторов для ряда целых чисел

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

Просто использование killall pulseaudio в терминале.

8
задан Daniel 30 August 2009 в 14:13
поделиться

9 ответов

Хеширование Zobrist может вам помочь. Вам нужно создать матрицу NxN случайных целых чисел, каждая ячейка, представляющая этот элемент i, находится в j-й позиции в текущей перестановке. Для данной перестановки вы выбираете значения N ячеек и xor их один за другим, чтобы получить ключ перестановки (обратите внимание, что уникальность ключа не гарантируется).

Суть этого алгоритма в том, что если вы переключаетесь на элементы в вашем перестановок, вы можете легко сгенерировать новый ключ из текущей перестановки, просто вычеркнув старый и вставив в новые позиции.

7
ответ дан 5 December 2019 в 07:59
поделиться

Судя по вашему вопросу и оставленным вами комментариям, я бы сказал, что вашу проблему невозможно решить.

Позвольте мне объяснить.

Вы говорите, что вам нужен уникальный хэш из вашей комбинации, поэтому давайте сделаем это правило №1:

  • 1: Нужен уникальный номер для представления комбинации произвольного количества цифр / чисел

Хорошо, тогда в комментарии вы сказали, что, поскольку вы используете довольно много чисел, хранить их в виде строки или еще чего-то в качестве ключа к хеш-таблице невозможно, из-за ограничений памяти. Итак, давайте перепишем это в другое правило:

  • 2: Невозможно использовать фактические данные, которые использовались для создания хэша, поскольку они больше не находятся в памяти

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

Извините, но вы не можете этого сделать.

Типичные алгоритмы хеширования производят относительно уникальные хеш-значения, поэтому, если вы не хотите принимать коллизии в том смысле, что новая комбинация может быть помечена как "уже увиденная", даже если это не так, тогда вам не повезло.

Если бы вы попробовали битовое поле, где каждая комбинация имеет бит, который равен 0 если это не было замечено, вам все равно понадобится большой объем памяти.

Для перестановки в n = 20, которую вы оставили в комментарии, у вас есть 20! (2,432,902,008,176,640,

6
ответ дан 5 December 2019 в 07:59
поделиться

Как предлагали другие, вы можете использовать хеширование для генерации целого числа, которое будет уникальным с высокой вероятностью. Однако, если вам нужно, чтобы целое число всегда было уникальным, вам следует ранжировать перестановки, то есть назначить им порядок. Например, обычным порядком перестановок для набора {1,2,3} является лексикографический порядок:

  1. 1,2,3
  2. 1,3,2
  3. 2,1,3
  4. 2 , 3,1
  5. 3,1,2
  6. 3,2,1

В этом случае id перестановки является ее индексом в лексикографическом порядке. Конечно, есть и другие методы ранжирования перестановок.

Создание идентификаторов в виде диапазона непрерывных целых чисел позволяет реализовать хранение обработанных перестановок в виде битового поля или логического массива.

3
ответ дан 5 December 2019 в 07:59
поделиться

Насколько быстро это должно быть?

Вы всегда можете собрать целые числа в виде строки, затем взять хэш этого числа, а затем просто взять первые 4 байта.

Для хеша вы действительно можете использовать любую функцию, например MD5 или SHA-256.

3
ответ дан 5 December 2019 в 07:59
поделиться

Вы можете 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 должно быть достаточно в качестве строкового идентификатора (если только ваш массив чисел не большой).

2
ответ дан 5 December 2019 в 07:59
поделиться

Не относится непосредственно к вопросу, но в качестве альтернативного решения вы можете использовать Trie tree в качестве структуры поиска. Деревья Trie очень хороши для операций со строками, их реализация относительно проста и должна быть быстрее (max n (k), где k - длина ключа), чем хеш-набор для большого количества длинных строк. И вы не ограничены в размере ключа (например, в обычном хеш-наборе в must int, а не больше). Ключом в вашем случае будет строка всех чисел, разделенных некоторым символом.

0
ответ дан 5 December 2019 в 07:59
поделиться

Подобно сообщению Бояна кажется, что лучший способ пойти - это установить детерминированный порядок перестановок. Если вы обрабатываете их в этом порядке, то нет необходимости выполнять поиск, чтобы увидеть, не выполнили ли вы уже какую-либо конкретную перестановку.

0
ответ дан 5 December 2019 в 07:59
поделиться

Простые степени будут работать: если 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 бита)

0
ответ дан 5 December 2019 в 07:59
поделиться

Преобразуйте каждое число в строку, объедините строки (через StringBuffer) и используйте содержимое StringBuffer в качестве ключа.

0
ответ дан 5 December 2019 в 07:59
поделиться
Другие вопросы по тегам:

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