Shannon-Fano-Elias编码

一.理论分析

Shannon-Fano-Elias编码是利用累积分布函数来分配码字。

不失一般性,假定取X={1,2,…m}。如果对于全部的x,有p(x)>0。定义累积分布函数F(X)为

其函数图形见下图所看到的。修正的累积分布函数为当中表示小于x的全部字符的概率和加上字符x概率的一般得到的值。由于随机变量是离散的,故累积分布函数所含的阶梯高度为p(x)。函数的值恰好与x相应的那个阶梯的中点。

我们如今要确定的唯一性,这样才干保证能够相应到相应的x。由于全部的概率值均为正值。若因此通过累积分布函数就能够得到相应的X。但普通情况下为十进制小数。要表示为二进制小数须要非常多比特位,(在编码实现的过程中要注意此处。若是C语言实现,要注意存储二进制比特位的数组的长度。此处极易发生数组越界)这在现实的编码中是并不可行的。因此我们须要取一个精度,究竟精确到哪一位呢?取到l(x)位就可以。

二.编码实现

Shannon-Fano-Elias编码是用C语言来实现的。

code数组的长度建议定的大一些,此处极易发生数组越界(这都是血的教训啊….)

主要的结构体例如以下:

  1. typedef struct
  2. {
  3. double px; //px概率值
  4. double Fx; //fx函数值
  5. double Fbax; //Fba(X)的值
  6. int lx; //编码的长度
  7. int code[A]; //存储二进制比特
  8. }SFE;

1.初始化结构体,输入p(x)

  1. void init_code(int code[],int i)
  2. {
  3. int j;
  4. for (j=0;j<A;j++)
  5. code[j] = 0;
  6. }
  7. void init_px(SFE SFEA[],int length)//初始化px
  8. {
  9. printf("请输入概率值:\n");
  10. int i;
  11. for(i=1;i<=length;i++)
  12. {
  13. scanf("%lf",&SFEA[i].px);
  14. init_code(SFEA[i].code,i);
  15. }
  16. }

2.计算fx累积分布函数

  1. void count_fx(SFE SFEA[],int length)//计算fx累积分布函数
  2. {
  3. double sum =0;
  4. int i,j;
  5. for (i=1;i<=length;i++)
  6. {
  7. for (j=1;j<=i;j++)
  8. {
  9. sum = sum + SFEA[j].px;
  10. }
  11. SFEA[i].Fx = sum;
  12. sum = 0;
  13. }
  14. }

3.计算

  1. void count_fbax(SFE SFEA[],int length)//计算fbax的函数值
  2. {
  3. int i,j;
  4. double sum = 0;
  5. for (i=1;i<=length;i++)
  6. {
  7. if (i==1)
  8. {
  9. SFEA[i].Fbax = SFEA[i].px/2.0;
  10. }
  11. else
  12. {
  13. for (j=1;j<i;j++)
  14. {
  15. sum = sum + SFEA[j].px;
  16. }
  17. SFEA[i].Fbax = sum + SFEA[i].px/2.0;
  18. sum = 0;
  19. }
  20. }
  21. }

4.计算lx的长度。lx向上取整

  1. void count_lx(SFE SFEA[],int length)//计算lx的长度,lx向上取整
  2. {
  3. int i;
  4. for (i=1;i<=length;i++)
  5. {
  6. SFEA[i].lx = ceil(log(1/SFEA[i].px)/log(2))+1;
  7. }
  8. }

5.转化为二进制比特位

  1. void decimal(double m,int code[])
  2. {
  3. int *p = code;
  4. if(m>ZERO)
  5. {
  6. m=m*NUM;
  7. *p = (long)m;
  8. p++;
  9. decimal(m-(long)m,p);
  10. }
  11. }
  12. void f_binary(SFE SFEA[],int length)
  13. {
  14. int i;
  15. for (i=1;i<=length;i++)
  16. {
  17. decimal(SFEA[i].Fbax,SFEA[i].code);
  18. }
  19. }

整个编码过程至此结束,由于数组操作比較多。所以要注意防止数组越界。

三.编码结果分析

1.先给出一个样例,其十进制小数均能够转化为有限位数的二进制小数。

2.这个样例中二进制小数表示可能为无线位数的小数,開始的时候我将code数组的大小定义为20,运行完1中都非常正常,到了这个样例,一直不停的发生数组越界,原因是由于,此例中二进制表示可能有无穷位数字。如果先转化二进制。再编码表示的话,code数组的长度要足够长。当然,你也能够仅仅存储到l(x)位。

这样就不用那么大的空间了。

源码下载地址:shannon-fanon-elias编码C语言实现

Reference:

信息论基础.Thomas M.Cover Joy A.Thomas著

Shannon-Fano-Elias编码的C语言实现的更多相关文章

  1. 根据Unicode编码用C#语言把它转换成汉字的代码

    rt 根据所具有的Unicode编码用C#语言把它转换成汉字的代码 var s = System.Web.HttpUtility.HtmlDecode(Utf8Str); var o = Newton ...

  2. 随机线性网络编码的C语言实现,实现可靠传输:原理(1)

    线性方程组,大家都不陌生吧.来一组 A11 *X1 + A12 *X2 + A13 *X3 + A14 *X4 =Q1 A21 *X1 + A22 *X2 + A23 *X3 + A24 *X4 =Q ...

  3. Java语言编码规范 - Java语言编码规范(中文版)(http://doc.javanb.com/code-conventions-for-the-java-programming-language-zh/index.html)

      目录 1 介绍 1.1 为什么要有编码规范 1.2 版权声明 2 文件名 2.1 文件后缀 2.2 常用文件名 3 文件组织 3.1 Java源文件 3.1.1 开头注释 3.1.2 包和引入语句 ...

  4. 随机线性网络编码的C语言实现,实现可靠传输:实现篇(2)

    伽罗华域(2^8)乘除法的编程实现

  5. 变长编码表 ASCII代码等长编码

    小结: 1.ASCII编码.GBK编码不是变长编码: 2.数据压缩: 示例: aabacdab → 00100110111010 → |0|0|10|0|110|111|0|10| → aabacda ...

  6. 为什么倒排索引不采用zlib这样的字典压缩算法——因为没法直接使用啊

    看了下压缩算法的发展历史,根据倒排索引的数据结构特点,个人认为zstd不适合做倒排索引压缩,举例说明下: 假设有一份文档倒排列表为:[300, 302, 303, 332],对于这组倒排数据,是没法* ...

  7. 无损压缩算法历史——熵编码是最早出现的,后来才有Lzx这些压缩算法

    Lossless   Entropy type Unary Arithmetic Asymmetric Numeral Systems Golomb Huffman  Adaptive Canonic ...

  8. Swift3.0语言教程删除字符与处理字符编码

    Swift3.0语言教程删除字符与处理字符编码 Swift3.0语言教程删除字符 Swift3.0语言教程删除字符与处理字符编码,在字符串中,如果开发者有不需要使用的字符,就可以将这些字符删除.在NS ...

  9. 1 byte 8 bit 1 sh 1 bit 2. 字符与编码在程序中的实现

    https://en.wikipedia.org/wiki/Shannon_(unit) 1字节(英语:Byte)=8比特(英语:bit) The shannon (symbol Sh), also ...

随机推荐

  1. Centos6.9 搭建rsync服务端与客户端 案例:全网备份项目

    rsync的企业工作场景说明 1)定时备份 1.1生产场景集群架构服务器备份方案项目 借助cron+rsync把所有客户服务器数据同步到备份服务器 2)实时复制 本地数据传输模式(local-only ...

  2. react事件代理

    参考:https://github.com/youngwind/blog/issues/107 首先回顾以下原生事件的两个方法:event.stopImmediatePropagation 和 eve ...

  3. Linux文件权限基础(一)

    Linux中每个文件或者目录对都有一组共9个基础权限位,没三位字符被分为一组,他们分别是属主权限位,用户组权限位,其他用户权限位. 示例: 权限位说明: r --read 可读权限 对应数字4 w - ...

  4. laravel中的视图合成器

    ==================================================================================================== ...

  5. python--subprocess,粘包现象与解决办法,缓冲区

    一. subprocess 的简单用法 import subprocess sub_obj = subprocess.Popen( 'dir', #系统指令 shell=True, #固定方法 std ...

  6. leepcode作业解析-5-15日

    1.删除排序数组中的重复项 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外 ...

  7. C语言文件操作 FILE结构体

    内存中的数据都是暂时的,当程序结束时,它们都将丢失.为了永久性的保存大量的数据,C语言提供了对文件的操作. 1.文件和流 C将每个文件简单地作为顺序字节流(如下图).每个文件用文件结束符结束,或者在特 ...

  8. 某比赛小记2- 从HTTP请求返回中获得答案

    题目:在A页面登录后,重定向到A页面,然后访问B页面,header中带一指定内容"Content":"2018",然后从response中读取answer的值. ...

  9. PAT Basic 1017

    1017 A除以B(20 分) 本题要求计算 A/B,其中 A 是不超过 1000 位的正整数,B 是 1 位正整数.你需要输出商数 Q 和余数 R,使得 A=B×Q+R 成立. 输入格式: 输入在一 ...

  10. POJ 1849 树的直径 Two

    如果一个点开始遍历一棵树再回到原点那么每条边走两次. 现在是两个人从同一点出发,那么最后遍历完以后两人离得越远越好. 最后两人所处位置的路径上的边走了一次,其他边走了两次. 要使总路程最小,两人最后停 ...