项目实战——基于LZ77变形和哈夫曼编码的GZIP压缩

文件压缩:

日常生活中有很多压缩的例子,比如给很长的名字取一个缩写——西安交通大学简称西交大,这样就给我们的生活提供了很大的便捷,那么什么又是文件压缩呢?文件压缩就是将文件通过一些方法变得更小,解压缩就是将文件还原,文件压缩将文件变得更小节省了内存,并且在网络上传输起来也变得很快,还具有一定的保密性,所以这个项目就是为了实现这个目的。


基于哈夫曼树的文件压缩

一、思想:
众所周知在32位平台下一个字节占八个bit位,假如我们文件中的数据是abbbcccccddddddd时,每个字节占用八个比特位,并且有字节重复的问题,这就为给我们提供了压缩的可能性,实际上根本不需要八位的编码我们就足以把a、b、c、d这四个字符区别出来,哈夫曼编码就提供了这样的一种思想——如果能对所有字节找到小于8个比特位的编码,然后用找到的编码对源文件中对应字节重新进行改写,就可以起到压缩源文件的效果,所以,哈夫曼压缩的本质是基于字节层面的压缩
二、步骤
在确定了我们要做什么之后的问题就是如何着手去实现了,分为压缩和解压缩两个部分:
1.压缩:

  • 对于文件的压缩我们之前也提到时要重构文件中出现字符的编码然后重构字节,所以我们要通过哈夫曼树获取字符的哈夫曼编码,首先要将文件中的字符信息统计出来,将字符信息放入哈夫曼树中,包括字符、这个字符在文件中出现的次数(作为哈夫曼树的权值)、字符的编码,我们将这三个信息封装为一个类作为构造哈夫曼树和获取哈夫曼编码的条件。
  • 在压缩文件的开始部分记录源文件的后缀、字符以及字符出现的次数。作用:解压缩重构哈夫曼树的前提。
  • 有了哈夫曼编码作为前提我们就可以对每个字符所对应的字节进行改写了,并将改写后的字节放入到压缩文件中。
    2.解压缩:
  • 读取压缩文件头部所保存的信息——源文件的后缀、源文件中出现的字符以及出现的次数,通过源文件的后缀确定解压缩文件的后缀并打开解压缩文件,通过字符信息重构哈夫曼树。
  • 根据重构的哈夫曼树进行解压缩
    三、源码

    https://github.com/xiangxiangya/no.2/tree/master/Compress/Compress

实战中的问题以及总结:

1.使用优先级队列作为哈夫曼树的底层结构时默认是大堆模式,也就是说此时优先级队列模板的第三个参数是用小于方式去比较的,构建出来的是大堆,堆顶元素是最大的,这与我们想要的结果不符,所以我们要自己写一个比较器,然后当作第三个模板参数传入,默认大堆(小于比较方式)、小堆(大于比较方式)
2.在哈夫曼树我们规定好编码‘0’、‘1’的方向,在叶子节点存放的无疑就是保存进来的字符信息,我们在获取编码的时候采用根节点向上获取编码的方式,此时得到的编码需要逆置才是正确的编码。
3.在压缩文件中需要保存哪些信息?在刚开始的时候我之抓住了压缩字节的特点,于是只将压缩后的数据保存在压缩文件中,但是在解压缩的过程中出现了问题,因为只有压缩数据而没有标准的话是根本无法对信息进行还原的,所以在压缩文件中还需要保存----->1. 源文件的后缀2. 字符次数所占的总行数3. 字符以及字符出现次数 4. 压缩数据。
4.起初在设计时将字符设置为char类型的数据,当源文件中有汉字的时候就产生了访问越界的现象,这是由于对于英文字母来说char就足够用了,而对于汉字来说就需要通过unsigned char来表示,因为unsigned char的取值范围更大。
5.对于大文件的压缩出现了解压缩时不完全的情况,是由于fread函数在文件读取时意外终止,通过查阅资料是由于文件的打开方式不对,在将文件的打开方式改为二进制读或二进制写时就解决了这个问题。

原文地址:https://blog.51cto.com/14239789/2472031

时间: 2024-10-07 10:27:18

项目实战——基于LZ77变形和哈夫曼编码的GZIP压缩的相关文章

基于哈夫曼编码的文件压缩(c++版)

本博客由Rcchio原创 我了解到很多压缩文件的程序是基于哈夫曼编码来实现的,所以产生了自己用哈夫曼编码写一个压缩软件的想法,经过查阅资料和自己的思考,我用c++语言写出了该程序,并通过这篇文章来记录一下自己写该程序学到的东西.因为本人写的程序在压缩率上,还有提升的空间,所以本文将不定期更新,但程序整体的思路不会有较大的改动. 一.基于哈夫曼编码可实现压缩文件的原理分析 在计算机中,数据的存储都是二进制的,并且以字节作为基本的存储单位,像英文字母在文本中占一个字节,汉字占两个字节,我们把这种每一

基于python的二元霍夫曼编码译码详细设计

一.设计题目 对一幅BMP格式的灰度图像(个人证件照片)进行二元霍夫曼编码和译码 二.算法设计 (1)二元霍夫曼编码: ①:图像灰度处理: 利用python的PIL自带的灰度图像转换函数,首先将彩色图片转为灰度的bmp图像,此时每个像素点可以用单个像素点来表示. ②:二元霍夫曼编码: 程序流程图: 详细设计: 统计像素点频率,首先通过python自带的PIL库的图像像素点读取函数read()获取灰度图像的所有像素点,通过循环遍历每个像素点,将每个出现的像素点值以及其次数以键值对的形式放入到pyt

基于哈夫曼编码的压缩解压程序

这个程序是研一上学期的课程大作业.当时,跨专业的我只有一点 C 语言和数据结构基础,为此,我查阅了不少资料,再加上自己的思考和分析,实现后不断调试.测试和完善,耗时一周左右,在 2012/11/19 完成.虽然这是一个很小的程序,但却是我完成的第一个程序. 源码托管在 Github:点此打开链接 一.问题描述: 名称:基于哈夫曼编码的文件压缩解压 目的:利用哈夫曼编码压缩存储文件,节省空间 输入:任何格式的文件(压缩)或压缩文件(解压) 输出:压缩文件或解压后的原文件 功能:利用哈夫曼编码压缩解

霍夫曼编码求节省空间

霍夫曼编码将频繁出现的字符采用短编码,出现频率较低的字符采用长编码.具体的操作过程为:i)以每个字符的出现频率作为关键字构建最小优先级队列:ii)取出关键字最小的两个结点生成子树,根节点的关键字为孩子节点关键字之和,并将根节点插入到最小优先级队列中,直至得到一棵最优编码树. 霍夫曼编码方案是基于______策略的.用该方案对包含a到f6个字符的文件进行编码,文件包含100000个字符,每个字符的出现频率(用百分比表示)如表1-3所示,则与固定长度编码相比,该编码方案节省了______存储空间.

哈夫曼树与哈夫曼编码

哈夫曼树与哈夫曼编码 术语: i)路径和路径长度 在一棵树中,从一个结点往下可以达到的孩子或孙子结点之间的通路,称为路径. 路径中分支的数目称为路径长度.若规定根结点的层数为1,则从根结点到第L层结点的路径长度为L-1. ii)结点的权及带权路径长度 若对树中的每个结点赋给一个有着某种含义的数值,则这个数值称为该结点的权. 结点的带权路径长度为:从根结点到该结点之间的路径长度与该结点的权的乘积. iii)树的带权路径长度 树的带权路径长度:所有叶子结点的带权路径长度之和,记为WPL. 先了解一下

C语言之霍夫曼编码学习

?1,霍夫曼编码描述哈夫曼树─即最优二叉树,带权路径长度最小的二叉树,经常应用于数据压缩. 在计算机信息处理中,"哈夫曼编码"是一种一致性编码法(又称"熵编码法"),用于数据的无损耗压缩.这一术语是指使用一张特殊的编码表将源字符(例如某文件中的一个符号)进行编码.这张编码表的特殊之处在于,它是根据每一个源字符出现的估算概率而建立起来的(出现概率高的字符使用较短的编码,反之出现概率低的则使用较长的编码,这便使编码之后的字符串的平均期望长度降低,从而达到无损压缩数据的目

数据压缩之经典——哈夫曼编码(Huffman)

(笔记图片截图自课程Image and video processing: From Mars to Hollywood with a stop at the hospital的教学视频,使用时请注意版权要求.) JPEG用哈夫曼编码(Huffman Encoder)作为其符号编码.哈弗曼编码是压缩算法中的经典,它理论上可以将数据编成平均长度最小的无前缀码(Prefix-Free Code). 为什么要进行编码? 关于Lena:莱娜图(Lenna)是指刊于1972年11月号<花花公子>(Pla

哈夫曼(Huffman)树与哈夫曼编码

声明:原创作品,转载时请注明文章来自SAP师太技术博客:www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将追究法律责任!原文链接:http://www.cnblogs.com/jiangzhengjun/p/4289610.html 哈夫曼树又称最优二叉树,是一种带权路径长最短的树.树的路径长度是从树根到每一个叶子之间的路径长度之和.节点的带树路径长度为从该节点到树根之间的路径长度与该节点权(比如字符在某串中的使用频率)的乘积. 比如有一串字符串如

数据结构:哈夫曼编码(php版)

演示网址:http://huffman.sinaapp.com/ 源文件下载地址:http://xiaocao.u.qiniudn.com/work/huffman-2013-12-19.zip 概述下: 哈夫曼树─即最优二叉树,带权路径长度最小的二叉树,经常应用于数据压缩. 在计算机信息处理中,"哈夫曼编码"是一种一致性编码法(又称"熵编码法"),用于数据的无损耗压缩.     简单的,就是靠权值排序,然后,转码,最优保存. 实现功能: 保存译码:在服务器端保存源