Huffman编码实现文本文件压缩(C++实现)

设计题目

输入一个文本文件名,统计该文件中各字符频率。首先对各字符进行Huffman编码,将该文件翻译成Huffman编码文件B;然后将Huffman编码文件译码成文件C,并对原文件与文件C进行比较。

算法思想描述

需求分析

  输入:文本文件(压缩文件)

  输出:压缩文件(文本文件)  (压缩率)、解压后的文件

  知识点:哈夫曼树、二叉树遍历、存储数据结构设计

      文件流操作、字符汉字编码方式、二进制文件读写

  重点:字符文件、汉字文件的压缩与解压

 解决问题要点

1.      文本文件,二进制文件及数据流的操作

2.      英文字符,中文字符的存储与识别(难点)

3.      压缩及解压的主要思想(重点)

4.      Huffman树的构造

5.      编码的获取

6.      压缩文件的存储形式[huffman编码信息及数据存储]

7.      对文本文件最后一个字符的处理[补位数:压缩,解压无错误]

主要设计及具体实现

l  压缩解压的实现思想及原理

定义:利用算法将文件有损或无损地处理,以达到保留最多文件信息,而令文件体积变小。

在文本文件中,一个ASCII码占用一个字节空间(1Byte),汉字由两个字节构成(区码和位码),区码和位码分别用ASCII码的161-255字符表示,共94*94=8836个【GB2312编码】

即,无论字符还是汉字,均可由ASCII码表示,我们可以以二进制文件形式将一个文本文件读入,分析每个ASCII码的频数,构造huffman树,并得到相应的编码。

编码是由0、1组成的一串数字,出现频率越高的字符,其编码越短,通过这个特性,我们可以将每8位组成一个新的字符(1Byte),输出到压缩文件中,达到压缩的目的。

例如:

已知  a: 000  b:10  c: 001  d:01   e:11 

如果其中的一段是::abcde 则处理如下:

补上两位

    a      b     c      d     e  

   000   10   001  01   11   0000  0000 0010

每次取8位,8位凑成1Byte,转化为相应ASCII码输出

最后一位一般不能刚好凑够8 bit 所以需要补上0(或被之前覆盖的1)

最后一位的个数记录为补位数,以char的形式存入文件最后一位

原来:  5*1Byte=5 Byte

处理后:3*1Byte=3 Byte

 

仅为原来的五分之三,达到了压缩的目的

字符,汉字处理方式

字符,即ASCII码,ASCII编码由8位组成,共256个字符,足够表示英文文本。

汉字,是考虑的重点,多方考虑下,我选择了系统支持的GB2312编码表,而非转化为UNICODE编码。GB2312的汉字编码占用两个字节,区码和位码分别由ASCII码表的161-255字符表示,共8836个汉字,足以承担汉字处理,而UNICODE编码表是变长编码,处理困难且不利于压缩。

汉字ASCII码八位1*******   一般字符编码八位0*******

处理的思想

以字符形式读入,每次读入一个字节(1Byte)进行处理,不去判断区分是字符还是汉字,只识别ASCII码,进行处理。

用unsigned char储存,字节编码为0到255

此处处理思想参考了Huffman编码实现文本文件压缩这篇文章的思想,并做了改进,使得一个字节的8位均能储存编码,在此感谢这位博主!

代码

代码请参考本人github仓库 Compression-software-text

https://github.com/Aefile/Compression-software-text-.git

测试结果

1. 英文文本: 

I have a dream.txt    《I have a dream》全文   

压缩前:8.56KB      

压缩后:4.73KB

压缩率:55%

测试结果:

压缩,解压成功!压缩效果不错

内容与原文件相同

用时0.198秒

英文压缩测试成功

2.中文文本:

鬼谷子.txt    《鬼谷子》   

压缩前:18.2KB

压缩后:13.4KB

压缩率:73%

测试结果:压缩,解压成功!

内容于原文件相同,无乱码

用时0.432秒

中文汉字测试成功

3.略大文件  

平凡的世界.txt   《平凡的世界》       

压缩前:1.62M

压缩后:1.25M

压缩率:76%

测试结果:压缩,解压成功!

内容于原文件相同,无乱码

压缩时间31.367秒

你可能感兴趣的:(数据结构)