规范霍夫曼编码整理

一些子大白话

初学阶段,若有错误感谢指正

规范霍夫曼编码提出的意义:

在没有规范的时候,编码端的码表解码端并不知道,如果再将码表传送,对于本身数据量不大的压缩来说,可能码表就会在存储中就占较大比重,反而是把相对不复杂的问题搞得麻烦。

那么我们想如果提前指定一个规则,让编码端按照这个规则编码,解码端按照这个规则解码,就可以不用再建立码表了。

规范霍夫曼编码

两个规则:
1.一组码中码字长度最小的第一个编码一定是0
2.当码字长度变化时,长码字是在上一个短码字基础上末尾+1后补0(码字长度变几位就补几位0);长度不变时直接+1(都是二进制运算)

举个栗子

假设一组码字码长为1 1 2 2 3 4
则码长最小是1,那么这个码字就是0;
第二个码字仍然是1,则根据规则2,可知这个码字是1;
第三个码字长度为2,则根据规则2前半部分,可知码长增加1位,则对应的码字应该是(哦豁,看来我一开始就不对了,码长1位的只能有1个,不然下面就不能继续了)

重新举个栗子

假设一组码字码长为1 2 3 4 4
根据上面的分析我们列表看一下

码长对应码字
10
210
3110
41110
41111

一组码长为2 4 5 5 6

码长对应码字
200
40100
501010
501011
6011000

那么如果一组码字其最长码字为8,我们就用8bit来记录每个码长有多少个码字。

比如一组码字码长为3 4 4 5 5 5 5 6 7 7 8 8 8
则用8bit记录:0 0 1 2 4 1 2 3
第一位0:码长为1的码字有0个
第二位0:码长为2的码字有0个
第三位1:码长为3的码字有1个
第四位2:码长为4的码字有2个

代码理解

图片来源于数据压缩课程课件图片来源于数据压缩课程课件
这里我们给了一组符号及对应码长,那么我们根据上面介绍的规则可以写出其对应的码字。

在代码之前我们要了解这几个数组的含义

  1. first[ ]

    first[n]=x:表示码长为n的码字的第一个码字为x(或者理解成码长为n的码字的最小值)
    比如:first[3]=000,first[5]=10100…

  2. index[ ]
    index[m]=y:表示码长为m的第一个码字在所有码字的第y个位置。
    比如:index[3]=0,index[5]=9…

  3. table[]
    table[t]=z:表示第t个位置的码字对应的符号为z;
    比如table[0]=a,table[1]=b,table[2]=c…

int len = 1; //初始化码字长度len
int code = bs.ReadBit(); //设置一个按位读取的函数,让code每次在码流中读取一位
while(code >= first[len])
{
	code << 1;
	code |=(bs.ReadBit());
	len++;
}
code >> 1;
len--;
//至此识别出来一个即时码 

循环部分分析

假设输入码流为011000011010…

lencodefirst[len]code 比first[len]大小
100相等,循环继续
201(1)0大于,循环继续
3011(3)0大于,循环继续
40110(6)0010(2)大于,循环继续
501100(12)10100(20)小于,循环结束

那么code >> 1后为0110,len=4;

int sym_index = index[len]+(code-first[len]);
int sym=table[sym_index];
lenindex[len]codefirst[len]sym_index
410110 (6)0010 (2)5

得出结果 table[5]=f;

由给出的符号和码字的对应可知,该代码可以正确解出。

  • 19
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值