【项目】哈夫曼树的应用:文件压缩
来源:互联网 发布:openwrt手机网络共享 编辑:程序博客网 时间:2024/06/05 07:41
在前几天写了哈夫曼树以及哈夫曼编码的博客:
http://blog.csdn.net/wenqiang1208/article/details/77261906
文件压缩
文件压缩的主要思想是利用哈夫曼编码来实现的,但是得到编码之前我们需要构建这棵树。那么利用什么来构建树呢?!这里,我们需要统计每个字符出现的次数,用次数来构建Huffman-Tree。假设我们现在有一个.txt的小文件,内容是”aaaabbbccd”。字符存在计算机中时以字节为单位的,因此我们需要将这些字符压缩成0、1表示的编码,0和1表示字节中的“位”,这样能大大降低文件的大小。
源文件的的大小10个字节,
压缩后一共19个比特位,不足1个字节后面补足0,一共3个字节。
为了实现文件压缩,需要对文件字符信息进行定义
字符信息结构体
包括字符,字符个数,以及字符压缩后的编码。
struct FileInfo{ FileInfo() : _count(0) {} /*FileInfo operator+(const FileInfo& FileInfoRight)//会改变原来的值 { this->_count += FileInfoRight._count; return *this; }*/ FileInfo operator+(const FileInfo& FileInfoRight) { FileInfo temp(*this); temp._count += FileInfoRight._count; return temp; } bool operator <(const FileInfo& FileInfoRight)const { return _count < FileInfoRight._count; } bool operator >(const FileInfo& FileInfoRight)const { return _count > FileInfoRight._count; } bool operator != (const FileInfo& FileInfoRight)const { return _count != FileInfoRight._count; } std::string _strCode;//存放当前字符压缩后的编码 unsigned char _ch;//当前字符 size_t _count;//统计字符个数};
对文件信息进行压缩时,需要在新文件中写入头部信息,因为进行解压时需要文件信息。
头部信息包括下面三个部分:
扩展名:(就是源文件的后缀名)
编码行数
编码行 (字符:字符个数)
实现文件压缩的步骤:
(1)打开文件,对文件字符信息进行统计。CountFileInfo函数
(2)根据字符出现的个数,构建哈夫曼树,后序遍历哈夫曼树获取字符编码。FillCode函数和_GenerateHuffmanCode函数
(3)进行文件压缩,写入新的文件中;
a、先把头部信息写入新文件的首部(因为进行解压时,需要用到信息)。WriteHead函数
b、遍历源文件,将每个字符的编码信息写入新文件中。CompressCore函数
文件解压
文件解压,根据文件压缩文件,进行还原源文件。
(1)先读取头部信息,重新构建哈夫曼树。
(2)根据字符编码信息,对哈夫曼树进行遍历,叶子结点信息就是字符信息。
(3)将叶子结点信息重新写入文件中。
文件解压时遇到的问题
(1)比如说“aaa”并没有构建哈夫曼树,那么并没有写入编码信息,
解决方法:直接写入字符信息,不需要转码
(2)压缩信息后面 补足的0,可能会被误读成压缩信息。
压缩以后的文件如果不够一个字节大小,会用0来代替空缺的比特位,这样带来的问题就是可能会多解压出字符。以上述的”aaaabbbccd”为例,压缩以后的编码为19比特位:00001111 11110110 100,计算机存储的最小单位为字节,因此这些编码会被存储为00001111 11110110 10000000,后边的五个0对我们来说就是多余的,如果不处理,就会多还原出5个a。
解决方法:给出一个charCount来统计所有字符串的个数,其实也就是根节点的值,每次还原出一个字符后,charCount就-1,直到charCount为0时说明所有字符都已经解压完成。
代码地址
https://github.com/WenQiangW/FileCompress
测试
使用BeyondCompared软件进行对比源文件和新还原的文件,看是否还原成功。
在huffman文件压缩下:
压缩一个1.2M左右的文件,能够到压缩0.9M左右,用时0.5秒左右。
压缩一个2.3M左右的文件,能够到压缩1.8M左右,用时0.8秒左右。
压缩一个8.3M左右的文件,能够到压缩6.7M左右,用时3秒。
- 【项目】哈夫曼树的应用:文件压缩
- GZIP文件压缩的应用
- bitmap压缩图片文件的压缩的git项目
- 图像压缩_文件压缩zlib的应用
- 我的第一个项目---文件压缩
- 文件压缩项目的有关问题
- 项目:文件的压缩与解压
- 哈夫曼树应用——文件压缩
- 小项目-文件压缩(哈夫曼树)
- 文件压缩项目
- 【数据结构】文件压缩项目
- [项目]文件压缩
- 项目 2 - 对称矩阵压缩存储的实现应用
- 课程设计哈夫曼树文件的压缩
- Huffman的应用之文件压缩与解压缩
- huffman树的应用——文件压缩
- C++项目之文件的压缩及解压缩
- 如何调试其他项目的压缩JS文件
- 如何取得Spring管理的bean
- Qt之在运行时加载共享库
- 关于内网IP和外网IP的一些发现
- C++之split字符串分割
- Gitlab CI 自动部署 asp.net core web api 到Docker容器
- 【项目】哈夫曼树的应用:文件压缩
- win10系统崩溃(unexpected_store_exception):Kernel-Processor-Power(ID:37)原因以及修复办法
- Python: sklearn库中数据预处理函数fit_transform()和transform()的区别
- 剑指Offer RotateArray 旋转数组的最小数字
- 并查集总结
- 组件套包Essential Studio for UWP 2017 v3发布,为图表添加新的选择器控件
- android 用户系统 umssdk快速集成 [mob]
- HDU6148
- php中常用正则表达式函数