Хранить много номеров как один уникальный номер

У меня есть необходимость хранить много чисел (я могу решить, какие числа) как один уникальный номер, из которого я должен быть в состоянии получить исходный номер.
Я уже знаю 2 способа сделать это:

1) Основная теорема арифметики (простые числа)
Скажем, у меня есть 5 значений, я назначаю простое число, отличное от 1, каждому значению

a = 2
b = 3
c = 5
d = 7
e = 13

Если я хочу сохранить a, b и c, я могу умножить их 2*3*5=30 и я знаю, что никакое другое произведение простых чисел не может быть 30. Затем, чтобы проверить, содержит ли значение, например, b, все, что мне нужно сделать, это 30 % b == 0

2) Битовая маска
Так же, как разрешения Linux, используйте степени 2 и суммируйте каждое значение

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

2

Решение

Если вы храните, скажем, числа с базовыми 10, то выполните преобразование с помощью чисел с базовыми 11. С увеличенной базой у вас появляется дополнительная «цифра». Используйте эту цифру в качестве разделителя. Таким образом, три базовых 10 числа «10, 42, 457» становятся «10A42A457»: одно базовое число 11 (с «A» в качестве дополнительной цифры).

В какой бы базе не находились ваши исходные числа, увеличьте базу на 1 и объедините, используя дополнительную цифру в качестве разделителя. Это даст вам один номер в увеличенной базе.

Это единственное число может быть сохранено в любой удобной для вас числовой базе: например, двоичное, динарное или шестнадцатеричное.

Чтобы получить исходные числа, просто конвертируйте их в основание 11 (или что-то еще) и замените лишнюю цифру разделителями.

ETA: Вам не нужно использовать основание 11. Одно число «10A42A457» также является действительным шестнадцатеричным числом, поэтому можно использовать любое основание от 11 или выше. С Hex легче работать, чем с базой 11.

1

Другие решения

Есть ли другой способ сделать это эффективно, когда у вас есть, например, тысяча значений?

Я не математик, но это базовая математика, все зависит от дальности

Диапазон 0-1: Вы хотите хранить 4 числа 0-1 — это в основном двоичная система

Number1 + Number2 * 2^1 + Number3 * 2^2 + Number4 * 2^3

Диапазон 0-50 Вы хотите хранить 4 номера 0-49

Number1 + Number2 * 50^1 + Number3 * 50^2 + Number4 * 50^3

Диапазон 0-X Вы хотите хранить N номеров 0-X

Number1 + Number2 * (X+1)^1 + Number3 * (X+1)^2 + ... + NumberN * (X+1)^(N-1)

Если у вас нет шаблона для ваших чисел (так что он может каким-то образом сжаться), другого пути нет.

Для компьютера также очень легко определить число в отличие от простых чисел.


@FlorainK комментарий указал мне на тот факт, что я пропустил

(я могу решить, какие номера)

Единственное логичное решение — дать ваши номера ссылок

0 is 15342
1 is 6547
2 is 76234
3 is "i like stack overflow"4 is 42141

так что вы будете работать диапазон 0-4 (5 вариантов) и любой длины комбинации. Используйте ссылку при «кодировании» и «декодировании» числа

тысяча ценностей?

так что вы будете работать с диапазоном 0-999

0 is 62342
1 is 7456345653
2 is 45656234532
...
998 is 7623452
999 is 4324234326453

Допустим, вы используете 64-битную систему и язык программирования / db, который работает с 64-битными целыми числами

2^64 = 18446744073709551616

ваш максимальный диапазон 1000^X < 18446744073709551616 где X количество номеров, которые вы можете хранить в одном 64-битном целом числе

Который только 6.

Вы можете хранить только 6 отдельных чисел 0-999, которые будут соответствовать одному 64-битному целому числу.

0,0,0,0,0,0 is 0
1,0,0,0,0,0 is 1
0,1,0,0,0,0 is 1000
999,999,999,999,999,999 is ~1e+18
1

Итак, вы хотите сохранить «a, b, c» или «a, b» или «a, b, c, d» или «a» и т. Д. (Спасибо @FlorianK)

в таком случае просто можно использовать побитовые операторы и степени двух

$a = 1 << 0; // 1
$b = 1 << 1; // 2
$c = 1 << 2; // 4
$d = 1 << 3; // 8
.. etc

скажем $flag имеет $a а также $c

$flag = $a | $c; // $flag is integer here

сейчас проверь

$ok = ($flag & $a) && ($flag & $c); // true
$ok = ($flag & $a) && ($flag & $b); // false

так что в 64-битной системе / языке / операционной системе вы можете использовать до 64 флагов, что дает вам 2 ^ 64 комбинации

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


Я вижу, что вы используете базу данных, и вы хотите сохранить это в БД.

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

1
По вопросам рекламы [email protected]