文章目录

  • 问题
  • 实验环境
  • 程序组成
  • 实现思路
  • 如何用二进制0/1表示字符 '0' / '1'
  • 源代码下载
  • 程序运行和结果:
  • 总结

问题

利用哈夫曼编码将英文文献进行压缩
注:哈夫曼算法及原理见博客https://blog.csdn.net/Little_ant_/article/details/104246904在此不再赘述。

实验环境

VS2017 C++

程序组成

main.cpp 文件里调用具体的函数实现整体上的功能。
      Huffm.h 文件中实现huffman算法的编码,以及译码到指定文件的功能。
      Input.h 文件中统计文本信息,然后作为huffman算法的输入。
      Output.h 文件中将目标文件通过huffman编码进行压缩。
      hello.txt 文件为需要被压缩的文件,即目标文件 。
      helloCompressed.txt 文件是被压缩之后得到的文件。
      HelloUnziped.tx 文件是解压缩之后得到的文件。

实现思路

1, 先熟悉huffman算法的逻辑,并进行实现。(以前比较熟)
      2, 构造huffman算法的输入,即统计文本信息,建立huffman树并完成huffman编码。
      3, 通过huffman编码来将hello.txt中的字符转换为对应的编码,压缩文件为helloCompressed.txt
      4, 通过译码算法来解压我们压缩过的文件,得到文件helloUnzipedtxt,并与目标文件hello.txt相对比。
      具体的编码方式:对文本中每一个出现的字符进行频度统计,进行编码。

如何用二进制0/1表示字符 ‘0’ / ‘1’

通过Huffm.h将源文件进行编码,所得到的信息有,所有的字符数量 (int 型),字符种类数(int 型),huffman树(struct*)和huffman编码(char**)。假设对字符’a’所得到的huffman编码字符串为char* str=”0101” ,如何转化为二进制序列 0101?从而实现压缩文件的功能。

这里通过c语言中的位操作符,左移和右移来定位到每一个bit上,从而对bit进行赋值,或读取每一个bit。代码如下:

 unsigned char ch1 = fgetc(streamin);//读源文件内容,逐字节来读取char value = 0;int pos = 0;int resIndex;int codeLen;while (ch1 != EOF){if (feof(streamin))break;resIndex = getHuffmanCode_index(data, ch1);if (resIndex == -1)return;char* code = hc[resIndex];//每个字符的Huffman编码codeLen = strlen(code);for (int i = 0; i < codeLen; i++)//一个一个比特位来进行放{value <<= 1;//先左移一位,如果code为1就进行下面的代码,把第一位变为1,为0就不处理//循环进行,就会把哪一位为1就把那一位置为1if (code[i] == '1')//得到二进制的1{value |= 1;//把原来为0的位置变为1,即就是写进1.}if (++pos == 8)//满8位写入文件{fputc(value, streamout);//把value写进去,里面存的8个位就是HuffmanCodevalue = 0;//重置,循环写pos = 0;}}ch1 = fgetc(streamin);}

ch1为源文件中读入的字符,code为该字符对应的huffman编码。value在此起到一个缓冲区的作用,一直在不停的左移,它是用来将字符 ‘1’ 转换为二进制 1的重点。假设编码序列为”0101111”,将其转换为二进制存储的过程如下:
      初始:value 00000000
      左移一位:value 00000000
      判断序列的第一位,发现其为0,那就左移一位:value的值为00000000
      判断序列的第二位,发现其为1,那就将上一步的value与00000001进行或操作,得到value值为:00000001 然后左移一位:00000010
      判断序列的第三位,发现其为0,那就左移一位:value的值为00000100
      判断序列的第四位,发现其为1,那就将上一步的value与00000001进行或操作,得到value值为:00000101 然后左移一位:00001010
      判断序列的第五位,发现其为1,那就将上一步的value与00000001进行或操作,得到value值为:00001011 然后左移一位:00010110
      判断序列的第六位,发现其为1,那就将上一步的value与00000001进行或操作,得到value值为:00010111 然后左移一位:00101110
      判断序列的第七位,发现其为1,那就将上一步的value与00000001进行或操作,得到value值为:00101111 然后左移一位:01011110

从而我们将字符串”0101111”转换为二进制bit存储在字节value变量中,此时的value变量值为 01011110 ,前面7位是字符串,现在在等待下一字符串序列。
      采用pos变量来记录左移的次数,如果左移8次,那就表示value的8个位已经存满了,就要将value输出到压缩文件helloCompressed.txt里面。清零pos,让value一直循环左移,直到将目标文件hello.txt中的字符全部读取。

解压缩过程同理。

源代码下载

https://download.csdn.net/download/Little_ant_/15452531 注:不需要积分哦

程序运行和结果:

将所有文件放在同一个执行目录下,如下:

      运行程序之后结果为:

      运行结果如下:

总结

压缩后文件helloCompressed.txt大小为4kB,而目标文件hello.txt的大小为7kB。并且解压之后文件helloUnziped.txt与目标文件一模一样。
      压缩率为近50%。

采用Huffman编码进行数据压缩相关推荐

  1. huffman编码压缩c语言,用Huffman编码对文件进行压缩的C语言实现

    本文介绍了采用Huffman编码对ASCII码文件进行压缩的基本原理,并用C语言程序实现了这个压缩过程.文中给出了比较完整的C语言程序代码,可以直接用于调试实验. 福 建电 脑 21 0 2年第 1期 ...

  2. Huffman编码文件压缩

    [问题描述] 编写一程序采用Huffman编码对一个正文文件进行压缩.具体压缩方法如下: 对正文文件中字符(换行字符''除外,不统计)按出现次数(即频率)进行统计 依据字符频率生成相应的Huffman ...

  3. 算法系列(二):贪心算法--Huffman编码

    算法系列(二):贪心算法--Huffman编码 一.分析 问题描述: 哈夫曼编码是广泛地用于数据文件压缩的十分有效的编码方法.其压缩率通常在20%-90%之间.哈夫曼编码算法使用字符在文件中出现的频率 ...

  4. Huffman 编码

    数据结构第五次作业--Huffman 编码 18级第五次作业(树)-Huffman编码文件压缩 我这里没有用到位运算,输入进output文件里面的仅仅是字符'0'和'1' [问题描述] 编写一程序采用 ...

  5. Huffman编码与译码

    Huffman树的构建说明 样例分析: 对于一个字符串输入 c b a x y y z z 若采用ASCII 编码方式,每一个字符都是char类型,每个字符所占空间为一个字节,因此8个字符就需要8个字 ...

  6. 【信息科学技术与创新】数据压缩的理论方法与现实意义 信息论 压缩编码 通信的数学理论 Huffman编码 LZ算法 虚幻引擎与数据压缩

    数据压缩的理论方法与现实意义 摘要 首先通过信息论引出数据压缩编码的理论方法 接着结合目前技术发展分析压缩编码的现实意义 最后总结思考未来通信与存储的压缩方法 Navigator 数据压缩的理论方法与 ...

  7. matlab实现数据压缩,【Matlab】Huffman编码如何实现数据压缩

    Huffman编码可用于数据压缩已经是人所共知的事实.但是具体说到如何实现编码,至少作者在实验中是遇到问题了的! 对数值串: [22006 22006 44004 87999 175989] --1* ...

  8. huffman编码译码器用c语言,基于哈弗曼编码的数据压缩C语言实现

    haod 摘要 数据压缩技术是一项重要实用的信息技术.信息时代的到来,信息量迅速增长,使得数据压缩也显得越来越重要.数据压缩有多种编码方法,大致可分为无损压缩编码和有损压缩编码.其中,Huffman ...

  9. 数据压缩之Huffman编码

    数据压缩之Huffman编码 实验介绍 实验环境介绍和项目使用方法 1.对.img图像文件进行Huffman编码 2.编写diff程序得到差值图像,并进行Huffman编码 3.使用其他图像码本对图像 ...

最新文章

  1. 滴滴高管今年集体不拿年终奖 员工奖励力度缩减一半
  2. flask 注册路由和蓝图
  3. SQL注入天书-ASP注入漏洞全接触
  4. pat 1034. Head of a Gang (30)
  5. 服务器本地文件,云服务器 本地文件
  6. 关于ORA-01187: cannot read from file because it failed verification tests 的处理方法
  7. 程序员谈网络改变我们的生活
  8. Eclipse SVN修改用户名和密码
  9. git reset简介
  10. Fiddler-半自动构造少量数据
  11. ajax调用方式汇总
  12. sklearn学习笔记之feature_selection(特征选择)
  13. 洛谷——【数据结构1-1】线性表
  14. arcgis悬挂点修改_ArcGIS拓扑编辑修正点位置的问题
  15. 【测试】嵌入式软件测试VS一般软件测试
  16. ISBN书号怎么查询
  17. 绵阳python培训_绵怎么组词
  18. GPU与CPU的区别
  19. 车羊问题c语言编程,再谈“羊车门”问题
  20. 为Android 模拟器加速

热门文章

  1. MXNET:深度学习计算-GPU
  2. File IO(NIO.2):路径类 和 路径操作
  3. 移动端常见的不同苹果手机media query汇总
  4. Android Activity初探
  5. Perl Nmap报告处理摸索(学习)
  6. python代码转成java_如何实现Java代码转换成python代码
  7. 逆向与分析-WebBrowserPassView消息分析
  8. Win64 驱动内核编程-32.枚举与删除注册表回调
  9. 【Linux 内核】宏内核与微内核架构 ( 操作系统需要满足的要素 | 宏内核 | 微内核 | Linux 内核动态加载机制 )
  10. 【ijkplayer】编译 Android 版本的 ijkplayer ⑥ ( 进入 ijkplayer-android/android 目录 | 执行 compile-ijk.sh 脚本完成编译 )