霍夫曼编码与解码
来源:互联网 发布:域名未授权 编辑:程序博客网 时间:2024/06/08 11:14
压缩软件:
给定一篇文章,只含有英文大小写字母和空格,统计该文件中各种字符的频率,对各字符进行Huffman编码,将该文件翻译成Huffman编码文件,再将Huffman编 码文件翻译成源文件。
运行结果如下
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;typedef struct{ int value; int p,l,r;}HTNode,*HuffTree;struct fact //因为不是每一篇文章中所有字符都会出现{ //所以结构体数组存储数组下标真正对应的字符ch以及权值weight char ch; int weight;};typedef char * * HuffCode; // 字符指针数组用于存储各个字符对应的编码typedef char * CHAR;void select(HuffTree &HT,int n,int &s1,int &s2); //查找HT中未被使用的权值最小的连个点的下标void HUFFTREE(HuffTree &HT,fact *ww,int n,HuffCode &HC); //建树函数,附带完成每一个字符对应的编码void BecomeCode(HuffCode &HC,int n,CHAR &Code,char *Text,int *match); //由已知的各个字符的编码完成全文的编码void Code_ToBe_Artical(CHAR &Code,HuffTree &HT,fact *Fact,int n); //由全文的编码,用已经建立的哈弗曼树完成解码int main(){ HuffTree HT=NULL; HuffCode HC; printf("请输入需要编码的文章\n"); char Text[20000]; CHAR Code = NULL; //指针用于存储文章最终的编码 gets(Text); int len=strlen(Text); int codeweight[54],match[54]; memset(codeweight,0,sizeof(codeweight)); for(int i=0;i<len;i++) // 统计频率 空格下标为0 ,(A~Z)下标分别为(1~26) (a~z)下标分别为(27~52) { if(Text[i]==' ') codeweight[0]++; else if(isupper(Text[i])) codeweight[Text[i]-'A'+1]++; else codeweight[Text[i]-'a'+27]++; } int n=0; fact Fact[54]; // 由于不是每一个字符都出现在文章中,将codeweight数组录入Fact结构体数组中 for(int i=0;i<=52;i++) { if(codeweight[i]!=0) { if(i==0) Fact[n].ch=' '; else if(i<=26) Fact[n].ch=i+'A'-1; else Fact[n].ch=i+'a'-27; match[i]=n; Fact[n++].weight=codeweight[i]; } } HUFFTREE(HT,Fact,n,HC); //建树函数,附带完成每一个字符对应的编码 BecomeCode(HC,n,Code,Text,match); //由已知的各个字符的编码完成全文的编码 Code_ToBe_Artical(Code,HT,Fact,n); //由全文的编码,用已经建立的哈弗曼树完成解码 return 0;}void select(HuffTree &HT,int n,int &s1,int &s2){ s1=s2=0; HT[0].value=0x7fffffff; for(int i=1;i<=n;i++) { if(HT[i].p!=0) continue; if(HT[i].value<HT[s1].value) { s2=s1; s1=i; } else if(HT[i].value<HT[s2].value) s2=i; }}void HUFFTREE(HuffTree &HT,fact *ww,int n,HuffCode &HC){ int m=n*2-1; HT = (HuffTree)malloc((m+1)*sizeof(HTNode)); //分配m+1个内存,是因为要存储m个数据,但是要从HT数组下标1开始 int i,j,f; fact *w=ww; HuffTree p; for(p =HT,p++,i=1;i<=n;i++,p++,w++) //对HT (1~n)赋值语句 { (*p).value=(*w).weight,(*p).p=0,(*p).l=0,(*p).r=0; } for(;i<=m;i++,p++) //对HT (n+1~m)赋值语句 { (*p).value=0,(*p).p=0,(*p).l=0,(*p).r=0; } int s1,s2; for(i=n+1;i<=m;i++) { select(HT,i-1,s1,s2); HT[s1].p=i,HT[s2].p=i; HT[i].l=s1,HT[i].r=s2; HT[i].value=HT[s1].value+HT[s2].value; } HC = (HuffCode)malloc((n+1)*sizeof(char *)); // 为字符指针数组分配内存 char *temp=(char *)malloc(n*sizeof(char)); temp[n-1]='\0'; for(i=1;i<=n;i++) { int start=n-2; for(j=i,f=HT[i].p;f!=0;j=f,f=HT[f].p) { if(HT[f].l==j) temp[start--]='0'; else temp[start--]='1'; } HC[i]=(char *)malloc((n-start)*sizeof(char)); strcpy(HC[i],&temp[++start]); } delete temp; printf("\n各个字符对应的编码\n"); for(i=1;i<=n;i++) { if(ww[i-1].ch==' ') printf("空格 --> "); else printf("%c --> ",ww[i-1].ch); puts(HC[i]); }}void BecomeCode(HuffCode &HC,int n,CHAR &Code,char *Text,int *match){ int len,i; //纯粹是用已知的文本Text和HC将文本转化为编码 len=strlen(Text); Code = (char *)malloc((len*n+1)*sizeof(char)); Code[0]='\0'; for(i=0;i<len;i++) { if(Text[i]==' ') strcat(Code,HC[1]); else if(Text[i]<='Z'&&Text[i]>='A') strcat(Code,HC[ match[Text[i]-'A'+1]+1 ]); else strcat(Code,HC[ match[Text[i]-'a'+27]+1 ]); } printf("\n文章编码为\n"); puts(Code);}void Code_ToBe_Artical(CHAR &Code,HuffTree &HT,fact *Fact,int n) //纯粹的使用已经建好的树,由上至下进行查询{ printf("\n将编码解码\n"); for(int i=0;Code[i]!='\0';i++) { int m=n*2-1,ok=1; while(1) { if(Code[i]=='0') { m=HT[m].l; if(HT[m].l==0) { printf("%c",Fact[m-1].ch); break; } } else if(Code[i]=='1') { m=HT[m].r; if(HT[m].r==0) { printf("%c",Fact[m-1].ch); ok=0; } } if(!ok) break; i++; } } printf("\n"); return ;}
0 0
- 霍夫曼编码与解码
- js 编码解码 与 java编码解码
- js 编码解码 与 java编码解码
- 霍夫曼编码与解码c++实现
- 加密与压缩,霍夫曼编码解码
- Base64编码与解码
- BASE64编码与解码
- BASE64编码与解码
- Base64编码与解码
- base64编码与解码
- huffman编码与解码
- UCS2编码与解码
- 编码与解码1
- 编码与解码2
- 批量编码与解码
- 编码与解码
- URL编码与解码
- URL编码与解码
- dos遍历目录文件
- 天池大数据竞赛----菜鸟-需求预测与分仓规划(源码大放送)
- 获取安卓音乐专辑图片
- 大型网站架构系列:电商网站架构案例(1)
- Test
- 霍夫曼编码与解码
- AsynSocket实现即时通讯
- 百度之星 2016 problem e 输入处理
- 如何实现结构体和文件之间实现读写--fopen文件流读写(fscanf/fprintf)
- 小型大数模拟
- 第十二周项目1-实现复数类中的运算符重载(1)
- Andorid 动画介绍
- 嗅探、中间人sql注入、反编译--例说桌面软件安全性问题
- C++ 默认构造函数深度解析