按:去年接手一个项目,涉及到一个一个叫做Mxpeg的非主流视频编码格式,编解码器是厂商以源代码形式提供的,但是可能代码写的不算健壮,以至于我们tcp直连设备很正常,但是经过一个UDP数据分发服务器之后,在偶尔有丢包的情况下解码器会偶发崩溃,翻了翻他们的代码觉得可能问题出在Huffman这一块。水平有限也没有看太懂他们的源码,而且我也不是科班出身当时对Huffman编码算法只是知道这么个名字,还好服务端软件那边做了修改,解决了丢包的问题。在回家过年的火车上想起这件事,阅读了一些关于Huffman编码的资料,算是对这个东西有了些通俗的认识,记在这里以防遗忘或者智力萎缩。
 
Huffman编码,是一种压缩编码算法,它利用“出现频率最大的信息应该用最短的码元来表示”这一原理对信息进行压缩。使用这种原理的编码算法统称“熵编码”。为了解释清楚Huffman编码的原理,我得先定义一些概念:
 
信息(Message)
含有某种语义的单元。比如拿常用的文本传输举例子,'a'就是个信息,它表示字母a,或者不定冠词a,又或者A片。总之它有一个预先定义的语义。
 
信息序列(Message Sequence)
信息排列组合组成的串。就像英文一样,光有字母是不行的,因为字母只有26个,但是单词有几百万个,所以要用字母的排列组合来构成单词,比如apple,再比如<a href="http: baike.baidu.com="" view="" 657095.htm?source="www.willlong.com"">这个单词。然后我们还用单词加空格组成句子来表达更复杂的意思(信息),比如"son of bitch",这也是一个序列
 
符号(Symbol)
我们用电子设备来传输信息,但是设备不认识信息,只认识电平,1和0。0和1被叫作符号。
PS: 据说中国有个教授研究能表达3个状态的量子逻辑,成果还挺厉害的,不知道靠谱否。
 
符号序列(Symbol Sequence)
同样,光有符号也是不行的,因为符号只有两个(0,1),消息却有很多,比如字母有26个,所以要用符号的排列组合来表示信息,继而表示出信息序列。比如你去内存里看C字符串"son of bitch",就是0和1组成的符号序列。
 
编码(Message Code)
对于一个信息/信息序列M,用一个符号序列C来表示,在这个映射中,我们称C为M的编码/编码序列(同时,我们不妨把这个映射的过程叫做编码,不会产生歧义)。
有了上面这些概念,我们很容易推知,在单位符号传输时间恒定的情况下,传输同样的消息,肯定是生成的编码序列越短,花费的时间就越短。那么为了提高传输效率,我们有必要找到一种编码算法,使得一个有限长信息序列编码生成的符号序列尽可能的短,大神Shannon称之为“最小冗余编码(minimum-redundancy code)”——事实上Shannon的定义和我这里不太一样,我这是山寨解释。另外为了解码需要,一个可行的编码算法还要符合两个基本限制
 
1.不同的信息不能编出同样的码,这个是天经地义的,不需要解释。
2.不需要额外的说明就能确定信息编码之间的界限,从这个条件引申,我们可以将其解释为不能有一个编码C1是另一个编码C2的前k位(也叫前缀k——kth prefix),比如01表示a,011表示b就是不合法的,因为给定符号序列011,如果没有额外说明,没法确定是a加上一个1还是b。虽然没有什么逻辑联系,但是看到第二条我就想到为什么大家都喜欢配置文件而不是xml,尤其是手写解析器的情况下。
进一步考虑,假设待编码序列中的信息空间有N种取值,用1到N表示,P(n)为消息n出现的频率(因为是已知序列,所以是频率而不是概率),L(n)为消息n编码后的长度,C(n)为消息n的编码。我们可以得到另外一些结论,首先,有:
    如果 P(1)<=P(2)<=...<=P(N)
    那么 L(1)>=L(2)>=...>=L(N)
也就是说,频率小的信息编码之后不能比频率大的信息更短,因为如果不这样的话,我们只要简单的互换两个信息的编码,就能减小编码序列的长度。然后我们再考虑L(N-1)和L(N),假设L(N-1)=4,那L(N)是几?显然根据刚得出的结论L(N)不能小于4,那能不能是比4大,比如5?如果真等于5的话,根据前面的限制2,C(N)的前4位必然没有在编码空间中出现过,那第5位还有必要么?显然没有了,我读到第4位就知道一定是N了,还要第5位干什么?L(N)不能比4小,也不能比4大,那只能是4,也就是说,结论是L(N)=L(N-1)。

[老文章搬家] 关于 Huffman 编码的更多相关文章

  1. [老文章搬家] [翻译] 深入解析win32 crt 调试堆

    09 年翻译的东西. 原文见:  http://www.nobugs.org/developer/win32/debug_crt_heap.html 在DeviceStudio的Debug编译模式下, ...

  2. Jcompress: 一款基于huffman编码和最小堆的压缩、解压缩小程序

    前言 最近基于huffman编码和最小堆排序算法实现了一个压缩.解压缩的小程序.其源代码已经上传到github上面: Jcompress下载地址 .在本人的github上面有一个叫Utility的re ...

  3. Huffman 编码压缩算法

    前两天发布那个rsync算法后,想看看数据压缩的算法,知道一个经典的压缩算法Huffman算法.相信大家应该听说过 David Huffman 和他的压缩算法—— Huffman Code,一种通过字 ...

  4. [转载]Huffman编码压缩算法

    转自http://coolshell.cn/articles/7459.html 前两天发布那个rsync算法后,想看看数据压缩的算法,知道一个经典的压缩算法Huffman算法.相信大家应该听说过 D ...

  5. Huffman编码实现压缩解压缩

    这是我们的课程中布置的作业.找一些资料将作业完毕,顺便将其写到博客,以后看起来也方便. 原理介绍 什么是Huffman压缩 Huffman( 哈夫曼 ) 算法在上世纪五十年代初提出来了,它是一种无损压 ...

  6. Huffman编码

    #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <cstdio> #include <cstri ...

  7. 【数据压缩】Huffman编码

    1. 压缩编码概述 数据压缩在日常生活极为常见,平常所用到jpg.mp3均采用数据压缩(采用Huffman编码)以减少占用空间.编码\(C\)是指从字符空间\(A\)到码字表\(X\)的映射.数据压缩 ...

  8. 优先队列求解Huffman编码 c++

    优先队列小析      优先队列的模板: template <class T, class Container = vector<T>,class Compare = less< ...

  9. Huffman编码实现电文的转码与译码

    //first thing:thanks to my teacher---chenrong      Dalian Maritime university /* 构造Huffman Tree思路: ( ...

随机推荐

  1. sql一个表中的数据插入到另外一个表中

    声名:a,b ,都是表 复制代码代码如下: --b表存在(两表结构一样)  insert into b select * from a  若两表只是有部分(字段)相同,则 复制代码代码如下: inse ...

  2. Python Socket 编程——聊天室示例程序

    上一篇 我们学习了简单的 Python TCP Socket 编程,通过分别写服务端和客户端的代码了解基本的 Python Socket 编程模型.本文再通过一个例子来加强一下对 Socket 编程的 ...

  3. L1-009. N个数求和

    https://www.patest.cn/contests/gplt/L1-009 原来写的找了好久还是有一个测试点没过, 虽说是道水题,但是今天一遍就过了还是挺高兴的. 送你机组数据 52/5 4 ...

  4. Java程序设计之算出一年第多少天

    可以直接拷贝运行. package year; import java.util.Scanner; public class year { public static void main(String ...

  5. [LeetCode] Find the Difference 寻找不同

    Given two strings s and t which consist of only lowercase letters. String t is generated by random s ...

  6. Codeforces Round #382(div 2)

    A.= = B. 题意:给出n个数和n1和n2,从n个数中分别选出n1,n2个数来,得到n1个数和n2个数的平均值,求这两个平均值的最大和 分析:排个序从后面抽,注意先从末尾抽个数小的,再抽个数大的 ...

  7. web前端开发中常用的尺寸和位置

    我们在日常web前端开发过程中,会经常用到各种尺寸和位置.通常是js做动画的时候.轮播图,滚屏动画,粒子,碰撞检测,拖拽,滚动加载等等.这里我将常用的尺寸和位置的获取进行总结,不包括canvas,SV ...

  8. CentOS下配置java环境变量classpath

    一. 需要配置的环境变量1. PATH环境变量.作用是指定命令搜索路径,在shell下面执行命令时,它会到PATH变量所指定的路径中查找看是否能找到相应的命令程序.我们需要把 jdk安装目录下的bin ...

  9. python学习之路 第二天

    1.import 导入模块 #!/usr/bin/python # -*- coding:utf-8 -*- import sys print(sys.argv) 2.字符串常用方法: 移除空白: s ...

  10. DataTable ajax分页+删除+查询+修改

    这个框架前前后后跳进了很多次坑,也算是本人比较愚笨吧做了很长的时间而积累的经验... dataTable用了很久,今天在此总结一下使用方法以及常用属性的解释. Html代码 : <div cla ...