Кодирование Элиаса Омеги - Elias omega coding

Кодирование Элиаса ω или же Кодирование Элиаса Омеги это универсальный код кодирование положительных целых чисел, разработанное Питер Элиас. Нравиться Гамма-кодирование Элиаса и Дельта-кодирование Элиаса, он работает, добавляя к целому числу префикс представления его порядок величины в универсальном коде. Однако, в отличие от этих двух кодов, Elias omega рекурсивно кодирует этот префикс; таким образом, их иногда называют рекурсивные коды Элиаса.

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

Чтобы закодировать номер N:

  1. Поставьте «0» в конце кода.
  2. Если N = 1, стоп; кодирование завершено.
  3. Подготовить двоичный представление N к началу кода. Это будет как минимум два бита, первый из которых равен 1.
  4. Позволять N равно количеству только что добавленных битов минус один.
  5. Вернитесь к шагу 2, чтобы добавить кодировку нового N.

Чтобы декодировать целое число с омега-кодом Элиаса:

  1. Начните с переменной N, установите значение 1.
  2. Если следующий бит равен «0», остановитесь. Расшифрованное число N.
  3. Если следующий бит равен «1», прочтите его плюс N больше битов и используйте это двоичное число в качестве нового значения N. Вернитесь к шагу 2.

Примеры

Коды Омега можно рассматривать как ряд «групп». Группа представляет собой либо один бит 0, который завершает код, либо два или более бит, начинающихся с 1, за которыми следует другая группа.

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

ЦенитьКодПредполагаемая вероятность
101/2
210 01/8
311 01/8
410 100 01/64
510 101 01/64
610 110 01/64
710 111 01/64
811 1000 01/128
911 1001 01/128
1011 1010 01/128
1111 1011 01/128
1211 1100 01/128
1311 1101 01/128
1411 1110 01/128
1511 1111 01/128
1610 100 10000 01/2048
1710 100 10001 01/2048
...
10010 110 1100100 01/8192
100011 1001 1111101000 01/131,072
10,00011 1101 10011100010000 01/2,097,152
100,00010 100 10000 11000011010100000 01/268,435,456
1,000,00010 100 10011 11110100001001000000 01/2,147,483,648

Кодировка для 1 гугол, 10100, это 11 1000 101001100 (заголовок длины 15 бит), за которым следует 333-битное двоичное представление 1 гугола, что составляет 10010 01001001 10101101 00100101 10010100 11000011 01111100 11101011 00001011 00100111 10000100 11000100 11001110 00001011 11110011 10001010 11001110 0110000000011 10001010011 10001010 11001110 0110000000011 01000011 00001000 10101000 00101110 10001111 00010000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 и завершающий 0, всего 349 бит.

Гугол в сотой степени (1010000) представляет собой 33220-битное двоичное число. Его омега-кодирование составляет 33 243 бита: 11 1111 1000000111000100 (22 бита), за которым следуют 33 220 бит значения и завершающий 0. Меньше Дельта-кодирование Элиаса, то же самое число имеет длину 33 250 бит: 000000000000000 1000000111000100 (31 бит), за которым следует 33 219 бит значения. Как журнал2(1010000) = 33219,28, поэтому в этом случае омега-кодирование и дельта-кодирование соответственно только на 0,07% и 0,09% длиннее оптимального.

Пример кода

Кодирование

пустота eliasOmegaEncode(char* источник, char* dest){    IntReader читатель(источник);    BitWriter битрайтер(dest);    пока (читатель.оставил())    {        int число = читатель.getInt();        BitStack биты;        пока (число > 1) {            int len = 0;            за (int темп = число; темп > 0; темп >>= 1)  // вычисляем 1 + этаж (log2 (num))                len++;            за (int я = 0; я < len; я++)                биты.pushBit((число >> я) & 1);            число = len - 1;        }        пока (биты.длина() > 0)            битрайтер.putBit(биты.popBit());        битрайтер.putBit(ложный);                        // записываем один ноль    }    битрайтер.Закрыть();    читатель.Закрыть();}

Расшифровка

пустота eliasOmegaDecode(char* источник, char* dest) {    BitReader битрейдер(источник);    IntWriter интрайтер(dest);    пока (битрейдер.оставил())    {        int число = 1;        пока (битрейдер.inputBit())     // потенциально опасно с искаженными файлами.        {            int len = число;            число = 1;            за (int я = 0; я < len; ++я)            {                число <<= 1;                если (битрейдер.inputBit())                    число |= 1;            }        }        интрайтер.положить(число);           // записываем значение    }    битрейдер.Закрыть();    интрайтер.Закрыть();}

Обобщения

Кодирование Elias omega не кодирует ноль или отрицательные целые числа. Один из способов кодирования всех неотрицательных целых чисел - это добавить 1 перед кодированием и затем вычесть 1 после декодирования. Один из способов закодировать все целые числа - настроить биекция, отображение всех целых чисел (0, 1, -1, 2, -2, 3, -3, ...) в строго положительные целые числа (1, 2, 3, 4, 5, 6, 7, ...) перед кодирование.

Смотрите также

Рекомендации

дальнейшее чтение

  • Элиас, Питер (Март 1975 г.). «Универсальные наборы кодовых слов и представления целых чисел». IEEE Transactions по теории информации. 21 (2): 194–203. Дои:10.1109 / tit.1975.1055349.
  • Фенвик, Питер (2003). «Универсальные коды». В Сайуд, Халид (ред.). Справочник по сжатию без потерь. Нью-Йорк, Нью-Йорк, США: Академическая пресса. С. 55–78. Дои:10.1016 / B978-012620861-0 / 50004-8. ISBN  978-0123907547.

внешняя ссылка