您的位置:首页 > 其它

Gamma codes(γ 编码)的编码和解码过程(encoding and decoding of Gamma codes)

2017-06-20 14:05 363 查看
一个和最优编码长度差距在常数倍之内的方法是γ 编码。γ 编码将间距G表示成长度(length)和偏移(offset)两个部分进行变长编码。G的偏移实际上是G的二进制编码,但是前端的1 被去掉①。比如,对13(二进制为1101)进行编码,其偏移为101。G的长度指的是偏移的长度,并采用一元编码。对于刚才的例子,偏移的长度是3 位,因此其长度部分的编码是1110。因此,13 的整个γ 编码是1110101,即长度部分1110 和偏移部分101 的连接。表5-5 中的右列中给出了一些其他数的γ 编码的例子。

对γ 编码解码时,首先读入一元编码直至遇到0 结束,比如在对1110101 解码时,会一开始读入前4 位1110。然后便知道后面的偏移部分的长度是3,因此,再正确读入后续的3 位编码101,补上原来去掉的前端的1,最后可以得到 101→1101 = 13。



代码如下:

package test3;

import java.util.LinkedList;

public class γCode {
public static void main(String[] args){
int n=0;
System.out.println("测试的值为:"+n);
String γCode=γEncode(n);
System.out.println("γ编码的结果为:"+γCode);                //输出γ编码的结果
int number=γDecode(γCode);
System.out.println("γ解码的结果为:"+number);               //输出γ解码的结果
n=1;
System.out.println("测试的值为:"+n);
γCode=γEncode(n);
System.out.println("γ编码的结果为:"+γCode);                //输出γ编码的结果
number=γDecode(γCode);
System.out.println("γ解码的结果为:"+number);               //输出γ解码的结果
n=13;
System.out.println("测试的值为:"+n);
γCode=γEncode(n);
System.out.println("γ编码的结果为:"+γCode);                //输出γ编码的结果
number=γDecode(γCode);
System.out.println("γ解码的结果为:"+number);               //输出γ解码的结果
n=24;
System.out.println("测试的值为:"+n);
γCode=γEncode(n);
System.out.println("γ编码的结果为:"+γCode);                //输出γ编码的结果
number=γDecode(γCode);
System.out.println("γ解码的结果为:"+number);               //输出γ解码的结果
}
public static String γEncode(int number){
LinkedList<String> byteStream=new LinkedList<>();   //创建list存放长度和偏移
String binary = Integer.toBinaryString(number);     //转换为而二进制,除0外其他均为1做开端
String length="";
String offset="";
String γCode="";                                    //初始化各变量
char first=binary.charAt(0);                        //取得首位的字符
if(first=='0'){
return γCode;                                   //如果首位为0,则返回空的γCode
}else{
offset=binary.substring(1, binary.length());      //首位为1,去取首位得到偏移
}
for(int i=1;i<binary.length();i++){
length+="1";
}
length+="0";                                  //得到长度
byteStream.add(length);
byteStream.add(offset);                       //分别添加长度和偏移到byteStream中
γCode+=byteStream.get(0);
γCode+=byteStream.get(1);                     //合并长度和偏移
return γCode;                                 //返回编码结果
}
public static int γDecode(String γCode){
int number=0;
if(γCode==""){
return number;                     //如果γCode为空,返回0;
}
int index=γCode.indexOf("0");          //用indexOf取得第一次出现0的下标
String offset=γCode.substring(index+1, γCode.length());        //取得偏移部分
String binary="1"+offset;                         //首位加1,取得二进制字符串
number=Integer.parseInt(binary,2);
return number;
}
}


结果为:

测试的值为:0

γ编码的结果为:

γ解码的结果为:0

测试的值为:1

γ编码的结果为:0

γ解码的结果为:1

测试的值为:13

γ编码的结果为:1110101

γ解码的结果为:13

测试的值为:24

γ编码的结果为:111101000

γ解码的结果为:24

利用γ 编码方式能够达到最优编码的2 倍左右(最优编码对应的分布的

熵较大)。对于任意分布,像γ 编码这种编码长度在最优编码长度的某个倍数之内的编码方式,

被称为通用性编码(universal code)。

除了通用性之外,γ 编码还具有两种适合于索引压缩的性质。第一,γ 编码方法是前缀无关

码(prefix-free code,也称prefix code),即一个γ 编码不会是另一个γ 编码的前缀。这也意味着

对于一个γ 编码序列来说,只可能有唯一的解码结果,不需要对编码进行切分,而如果切分则

会降低解码的效率。γ 编码方法的第二个性质是参数无关(parameter free)性。对于很多其他高

效的编码方式,需要对模型(比如二项式分布模型)的参数进行拟合使之适应于索引中间距的

分布情况,而这样做会加大压缩和解压缩的实现复杂性,比如,必须对这些参数进行存储和检

索。另外,在动态索引环境下,间距的分布会变化,因此原有的参数可能不再合适。而对于参

数无关编码方法来说,上述问题就不存在。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  信息检索