Huffman编码文件压缩

【问题描述】

编写一程序采用Huffman编码对一个正文文件进行压缩。具体压缩方法如下:

<!--[if !supportLists]-->1.    <!--[endif]-->对正文文件中字符(换行字符'\'除外,不统计)按出现次数(即频率)进行统计

<!--[if !supportLists]-->2.    <!--[endif]-->依据字符频率生成相应的Huffman树(未出现的字符不生成)

<!--[if !supportLists]-->3.    <!--[endif]-->依据Huffman树生成相应字符的Huffman编码

<!--[if !supportLists]-->4.    <!--[endif]-->依据字符Huffman编码压缩文件(即按照Huffman编码依次输出源文件字符)。

说明:

<!--[if !supportLists]-->1.    <!--[endif]-->只对文件中出现的字符生成Huffman,注意:一定不要处理\n,即不要为其生成Huffman码。

<!--[if !supportLists]-->2.    <!--[endif]-->采用ASCII码值为0的字符作为压缩文件的结束符(即可将其出现次数设为1来参与编码).

<!--[if !supportLists]-->3.    <!--[endif]-->在生成Huffman树时,初始在对字符频率权重进行(由小至大)排序时,频率相同的字符ASCII编码值小的在前;新生成的权重节点插入到有序权重序列中时,出现相同权重时,插入到其后(采用稳定排序)。

<!--[if !supportLists]-->4.    <!--[endif]-->遍历Huffman树生成字符Huffman码时,左边为0右边为1。

5.    源文件是文本文件,字符采用ASCII编码,每个字符占8位;而采用Huffman编码后,高频字符编码长度较短(小于8位),因此最后输出时需要使用C语言中的位运算将字符Huffman码依次输出到每个字节中。

【输入形式】

对当前目录下文件input.txt进行压缩。

【输出形式】

将压缩后结果输出到文件output.txt中,同时将压缩结果用十六进制形式(printf("%x",...))输出到屏幕上,以便检查和查看结果。

【样例输入1】

若当前目录下input.txt中内容如下:

aaabbc

【样例输出1】

15f0

 同时程序将压缩结果输出到文件output.txt中。

【样例说明】

输入文件中字符的频率为:a为3,b为2,c为1,此外,\0字符将作为压缩文件的结束标志,其出现次数设为1。因此,采用Huffman码生成方法,它们的Huffman编码分别为:

a : 0

b : 10

c : 111

\0 : 110

因此,最终文件压缩结果(按位)为:

0001010111110000

将上述结果按字节按十六进制输出到屏幕上则为15f0(即0001010 111110000的十六进制表示)。

说明:采用Huffman码输出字符序列长度为:1+1+1+2+2+3+3=13(位),由于C语言中输出的最小单位为字节(8位),因此,最后补了三个位0,压缩后实际输出为2个字节。由于文本文件是按ASCII来解释的,因此,以文本方式打开压缩文件将显示乱码(最好用二进制文件查看器来看)。

【样例输入2】

若当前目录下input.txt中内容如下:

do not spend all that you have.do not sleep as long as you want.

【样例输出2】

ea3169146ce9eee6cff4b2a93fe1a5d462d21d9a87c0eb2f3eb2a9cfe6cae

同时程序将压缩结果输出到文件output.txt中。

【题解】

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<string.h>
  4 
  5 struct cc
  6 {
  7     char c;
  8     int num;
  9 };
 10 struct Huff
 11 {
 12     struct cc ccount;
 13     struct Huff *left,*right;
 14     struct Huff *next;
 15 };
 16 struct Huff *head=NULL;
 17 char Huffman[9];
 18 char Code[128][9];
 19 
 20 void read(FILE *fp,struct cc ccount[]);
 21 void insertSortLink(struct Huff *p);
 22 void creatList(struct cc ccount[]);
 23 void creatHuffman(void);
 24 void creatCode(struct Huff *p,char code,int level);
 25 void madeZIP(FILE *src,FILE *obj);
 26 
 27 int main()
 28 {
 29     FILE *fp,*fq;
 30     struct cc ccount[128];
 31     int i;
 32     for(i=0;i<128;i++)
 33     {
 34         ccount[i].c=0;
 35         ccount[i].num=0;
 36     }
 37 
 38     if((fp=fopen("input.txt","r"))==NULL)
 39         exit(-1);
 40     if((fq=fopen("output.txt","w"))==NULL)
 41         exit(-1);
 42 
 43     read(fp,ccount);
 44     creatList(ccount);
 45     creatHuffman();
 46     creatCode(head,'0',0);
 47     madeZIP(fp,fq);
 48 
 49     return 0;
 50 }
 51 
 52 void read(FILE *fp,struct cc ccount[])
 53 {
 54     char c;
 55     while((c=fgetc(fp))!=EOF)
 56         if(c!='\n')
 57         {
 58             ccount[c].c=c;
 59             ccount[c].num++;
 60         }
 61     ccount[0].c='\0';
 62     ccount[0].num=1;
 63     return;
 64 }
 65 void insertSortLink(struct Huff *p)
 66 {
 67     struct Huff *q=NULL,*r=NULL;
 68     if(head==NULL)
 69         head=p;
 70     else
 71     {
 72         q=head;
 73         if(p->ccount.num<q->ccount.num)
 74         {
 75             p->next=q;
 76             head=p;
 77         }
 78         else
 79         {
 80             while(q!=NULL && p->ccount.num>=q->ccount.num)
 81             {
 82                 r=q;
 83                 q=q->next;
 84             }
 85             p->next=q;
 86             r->next=p;
 87         }
 88     }
 89     return;
 90 }
 91 void creatList(struct cc ccount[])
 92 {
 93     int i;
 94     struct Huff *p;
 95 
 96     for(i=0;i<128;i++)
 97         if(ccount[i].num!=0)
 98         {
 99             p=(struct Huff *)malloc(sizeof(struct Huff));
100             p->ccount=ccount[i];
101             p->left=p->right=p->next=NULL;
102             insertSortLink(p);
103         }
104     return;
105 }
106 void creatHuffman(void)
107 {
108     struct Huff *p;
109     while(head->next!=NULL)
110     {
111         p=(struct Huff *)malloc(sizeof(struct Huff));
112         p->ccount.num=head->ccount.num+head->next->ccount.num;
113         p->left=head;
114         p->right=head->next;
115         p->next=NULL;
116         head=head->next->next;
117         insertSortLink(p);
118     }
119     return;
120 }
121 void creatCode(struct Huff *p,char code,int level)
122 {
123     if(level!=0)
124         Huffman[level-1]=code;
125     if(p->left==NULL && p->right==NULL)
126     {
127         Huffman[level]='\0';
128         strcpy(Code[p->ccount.c],Huffman);
129     }
130     else
131     {
132         creatCode(p->left,'0',level+1);
133         creatCode(p->right,'1',level+1);
134     }
135     return;
136 }
137 void madeZIP(FILE *src,FILE *obj)
138 {
139     unsigned char *pc,hc;
140     int c=0,i=0;
141     fseek(src,0,SEEK_SET);
142     do
143     {
144         c=fgetc(src);
145         if(c==EOF)
146             c=0;
147         for(pc=Code[c];*pc!='\0';pc++)
148         {
149             hc=(hc<<1)|(*pc-'0');
150             i++;
151             if(i==8)
152             {
153                 fputc(hc,obj);
154                 printf("%x",hc);
155                 i=0;
156             }
157         }
158         if(c==0 && i!=0)
159         {
160             while(i++<8)
161                 hc=(hc<<1);
162             fputc(hc,obj);
163             printf("%x",hc);
164         }
165     }while(c);
166     return;
167 }

猜你喜欢

转载自www.cnblogs.com/tuoniao/p/10346434.html