文件压缩与解压:霍夫曼编码
由于计算机的存储空间,文件传输时间成本等条件的限制,产生了对文件进行压缩从而减少文件大小的需求,各种压缩算法及其技术应运而生。其中的霍夫曼编码作为无损压缩当中最好的方法,受到了广泛的应用。
霍夫曼编码(Huffman Coding):
霍夫曼编码是一种无损压缩算法,于1952年由Divid A. Huffman在其博士论文《A Method for the Construction of Minimum-Redundancy Codes》提出。基本原理是利用二进制位代替原先字符进行存储,减少文件计算机存储的总位数从而减少文件的大小。下面用一个实例来说明其原理。
实例:
输入一个文本文件,根据Huffman算法原理对文件进行压缩,将压缩后的所有字符输入到另外一个文件上。
注意:实际要对文件进行压缩需要使用二进制的方式读取文件,构造Huaffman树,接着求出每个字符对应的Huffman编码,得到的编码是二进制是0和1,,而非字符型的0和1。为了说明Huffman编码的原理在本文中我使用的是字符型的0和1(下面会有解释说明)。
Huffman 编码是一种前缀编码,即频率越高的字符对应的编码长度越短。相对于等长度的编码来讲,大多数情况下总编码长度要短的多。对上文给的实例,其实现主要有以下几个步骤:
- 遍历所有字符
遍历文件所有的字符,并统计文件中不相同的字符即其出现的个数。
代码如下:
1 /** 2 读取文本文件,遍历文件中所有的字符,统计每个字符出现的频率,将字符和其对应的频数存储 3 在huffmantable结构体中,并且返回不同字符的个数 4 **/ 5 int readfile(char *filename,huffmantable *node) 6 { 7 8 char temp; 9 int length,i; 10 FILE *file; 11 errno_t err; 12 13 length=0; 14 15 err=fopen_s(&file,filename,"r"); 16 17 if(err!=0) 18 { 19 printf("the file can not open!\n"); 20 } 21 else 22 { 23 while((temp=fgetc(file))!=EOF) 24 { 25 if(length==0) 26 { 27 node[0].character=temp; 28 node[0].count=1; 29 length++; 30 31 } 32 else 33 { 34 for(i=0;i<length;i++) 35 { 36 if(node[i].character==temp) 37 { 38 39 node[i].count=node[i].count+1;//特别注意node.count没有初始化 40 break; //break:执行break后不执行其后的语句 41 } 42 } 43 if(i==length) 44 { 45 node[length].character=temp; 46 node[length].count=1; 47 length++; 48 } 49 } 50 } 51 } 52 53 fclose(file); 54 return length; 55 }