Вот один из способов.Во-первых, вычтите одно из каждого из ваших маленьких чисел.Для вашего примера входные данные, которые приводят к
0 1 3 4 2 4 1 2 0 1 2 3
Теперь обработайте это как представление целого числа с основанием 5.(Вы можете выбрать либо самую значимую цифру первой или последней.) Рассчитать число в двоичном виде, что означает то же самое.Теперь у вас есть одно целое число, которое «сжало» вашу строку из маленьких чисел.Поскольку вы не показали свой собственный код, я просто остановлюсь здесь.Вы сможете легко реализовать это.
Поскольку у вас будет не более 16 маленьких чисел, максимальное полученное значение из этого алгоритма будет 5^16
, что составляет 152,587,890,625
.Это вписывается в 38
бит.Если вам нужно хранить меньшие числа, чем это, преобразуйте полученное значение в другую, большую базу чисел, такую как 2^16
или 2^32
.Первое приведет к 3 числам, последнее к 2.
@ SergGr указывает в комментарии, что этот метод не показывает число закодированных целых чисел.Если это не сохраняется отдельно, это может быть проблемой, так как метод не различает начальные нули и закодированные нули.Есть несколько способов справиться с этим, если вам нужно количество целых чисел, включенных в сжатие.Вы можете потребовать, чтобы старшая цифра была 1
(первая или последняя зависит от того, где находится старшая цифра.) Это увеличивает количество битов на единицу, поэтому теперь вам может потребоваться 39
бит.
Вот игрушечный пример кодирования переменной длины .Предположим, мы хотим закодировать две строки: 1 2 3
и 1 2 3 0 0
.Как результаты будут отличаться?Давайте рассмотрим два числа из 5 цифр 321
и 00321
.Они представляют собой одно и то же значение, но все же давайте преобразуем их в base-2, сохраняя заполнение.
1 + 2*5 + 3*5^2 = 86 dec = 1010110 bin
1 + 2*5 + 3*5^2 + 0*5^3 + 0*5^4 = 000001010110 bin
Эти дополнительные 0
во второй строке означают, что наибольшее 5-значное число base-5 44444
имеет представление base-2 110000110100
, поэтому двоичное представление числа дополняется до одинакового размера.
Обратите внимание, что нет необходимости дополнять первую строку, потому что самая большая 3-значная base-5число 444
имеет представление base-2 1111100
, то есть такой же длины.Для исходной строки 3 2 1
в этом случае также потребуется некоторое заполнение, поэтому заполнение может потребоваться, даже если верхние цифры не 0
.
Теперь давайте добавим наиболее значимый 1
кдвоичные представления и это будут наши закодированные значения
1 2 3 => 11010110 binary = 214 dec
1 2 3 0 0 => 1000001010110 binary = 4182 dec
Существует много способов декодировать эти значения обратно.Один из самых простых (но не самых эффективных) состоит в том, чтобы сначала вычислить число цифр из базовых 5, вычислив floor(log5(encoded))
, а затем удалить верхний бит и заполнить цифры одну за другой, используя мод 5, и разделить на 5 операций.
Очевидно, что такое кодирование переменной длины всегда добавляет ровно 1 бит служебной информации.