哥伦布编码是一个针对整数的变长编码方式,详细介绍可以看维基百科。这里简单介绍下:
哥伦布编码使用指定的整数 M 把输入的整数分成两部分:商数 q、余数 r。 商数当做一元编码,而余数放在后面做为可缩短的二进制编码。
将整数变为一元编码非常简单:q 的一元编码结果就是 q 个 1 加上 1 个 0。如下表:
整数 | 一元编码 |
---|---|
0 | 0 |
1 | 10 |
2 | 110 |
3 | 1110 |
4 | 11110 |
5 | 111110 |
6 | 1111110 |
一元编码可以用以下代码实现;
function unary_encoding(q) {return (1 <<(q &#43; 1)) - 2; }
将 M 选为 64 时&#xff0c;余数取值区间为 [0, 64)&#xff0c;只需要用 6 位二进制表示。将待处理的数组每一项都除以 64&#xff0c;并将商数和余数分别做一元编码和二进制编码&#xff0c;得到如下结果&#xff1a;
整数 | 商数 | 余数 | 商数一元编码 | 余数二进制编码 |
---|---|---|---|---|
151 | 2 | 23 | 110 | 010111 |
41 | 0 | 41 | 0 | 101001 |
16 | 0 | 16 | 0 | 010000 |
61 | 0 | 61 | 0 | 111101 |
192 | 3 | 0 | 1110 | 000000 |
表格中每一行后两列拼起来就是该整数对应的哥伦布编码&#xff0c;可以看到&#xff0c;64 以下的整数编码后会变短。
这段代码运行结果如下&#xff1a;
["110010111", "0101001", "0010000", "0111101", "1110000000"]
摘自&#xff1a;https://imququ.com/post/golomb-coded-sets.html
go语言的实现&#xff1a;
https://github.com/tcnksm/go-casper/blob/master/internal/encoding/golomb/golomb.go
https://github.com/dave-andersen/deltagolomb/blob/master/deltagolomb.go
GOLOMB-RICE 编码
Golomb-Rice是Golomb编码的一个变种&#xff0c;它给Golomb编码的参数m添加了个限制条件&#xff1a;m必须是2的次幂。这样有两个好处&#xff1a;
不需要做模运算即可得到余数r&#xff0c;
r &#61; N & (m - 1)
对余数r编码更为简单&#xff0c;只需要取r二进制的低\(\log_2(m)\)位即可。
则Golomb-Rice的编码过程更为简洁&#xff1a;
初始化参数m&#xff0c;m必须为2的次幂 计算q和r&#xff0c;
q &#61; N / m ; r &#61; N & (m - 1)
使用一元编码编码q 取r的二进制位的低\(\log_2(m)\)位作为r的码字。