1、哈夫曼编码与译码课程设计第1章 需求分析Huffman编码和译码根据给定的字符集和各字符的频率值,求出其中给定字符Huffman编码,并针对一段文本(定义在该字符集上)进行编码和译码,实现一个Huffman编码/译码系统。要求设计类(或类模板)来描述Huffman树及其操作,包含必要的构造函数和析构函数,以及其他能够完成如下功能的成员函数:求Huffman编码输入字符串,求出编码输入一段编码,实现译码并设计主函数测试该类。第2章 总体设计图2.1主函数:对输入的字符段进行存储,并对字符数和对应的权值(字符个数)进行统计存储。哈夫曼树初始化函数:对给定的字符数和权值,创建一棵哈夫曼树。权值大小比
2、较函数:找到每次所给集合的最小值和次小值,并返回给哈夫曼树初始化函数。哈夫曼树编码函数:对创建的哈夫曼树,为左孩子的赋值为0,右孩子赋值为1,然后对叶子结点依次编码。哈夫曼树译码函数:对输入的01二进制数一一与叶子结点的编码依次比较匹配。第3章 抽象数据类型定义3.1 哈夫曼编码与译码抽象数据类型的设计enum Childnone,lchild,rchild; /采用枚举,标记是左孩子还是右孩子class element /元素类public:/类的公有成员 elememt(); /构造函数 void change(char l,char *c,int p,Child h,int w) /对对
3、象进行修改操作 void getparent(int p) /对父结点的值进行修改操作 void geta(Child h) /对孩子结点进行修改操作 void getweight(int w) /对权值进行修改操作 int returnweight() /返回权值操作 friend void Select(element h,int k,int *a,int *b);/友元函数的声明 friend void HuffmanTreeCode(element HT); friend void HuffmanTreeYima(element huff,char cod,int b);private
4、:/类的私有成员 char letter,*code; /letter为字符,*code指向编码字符串 int weight; /权值 int parent; /父结点 Child a; /为父结点的左孩子还是右孩子;第4章 详细设计4.1 工程视图图4.1工程视图4.2 类图视图图4.2类图视图4.3 函数的调用关系如下图:图4.3函数调用关系图4.4 主程序流程图4.5 主要算法的流程图图4.5.1哈夫曼编码函数图4.5.2哈夫曼译码函数第5章 测试图5.1哈夫曼编码与译码第6章 总结这次课程设计写得比较仓促,程序许多处仍需要完善和修改。写课程设计的过程中也暴露出自身的许多不足,比如对c+
5、语言有许多遗忘,比如把算法思想付诸实际代码的能力仍然不足。课程设计的过程也是对自己所学的知识回顾和检验的过程,在这期间不断遇到问题和解决问题也使我对所学过的知识有着更深层次的认识,编程能力也有很大的进步。对于程序,不足之处是友元函数的定义使得类的封装性大大降低,程序的主函数不够简明,没有进一步细分函数的功能等。附录:程序代码#include #include#include #include #include const int Lengh=1000; /最大长度为1000char coding100; /存储二进制字符串int n; /定义全局变量ofstream file1(编码.txt)
6、; /创建编码保存文件ofstream file2(译码.txt); /创建译码保存文件enum Childnone,lchild,rchild; /采用枚举标记事左孩子还是右孩子class elementpublic: elememt(); void change(char l,char *c,int p,Child h,int w) code=c; letter=l; a=h; weight=w; parent=p; void getparent(int p) parent=p; void geta(Child h) a=h; void getweight(int w) weight=w;
7、 int returnweight() return weight; friend void Select(element h,int k,int *a,int *b); friend void HuffmanTreeCode(element HT); friend void HuffmanTreeYima(element huff,char cod,int b);private: char letter,*code; /letter为字符,*code指向编码字符串 int weight; /权值域 int parent; /父结点序号 Child a; /为父结点的左孩子还是右孩子;void
8、 Select(element h,int k,int *a,int *b);/寻找最小和次小节点的序号void InitHuffmanTree(element huffTree,char t,int w) /哈夫曼树的初始化 int i,m=2*n-1,s1,s2; /no+n2=n 所以一要申请m个空间 for(i=0;in;i+) /初始前n个结点 huffTreei.change(ti,0,-1,none,wi); for(;i=m;i+) /后m-n个结点置空 huffTreei.change( ,0,-1,none,0); for(i=n;im;i+) /建立哈夫曼树 Select
9、(huffTree,i-1,&s1,&s2); /在huffTree中找权值最小的两个结点s1,s2 huffTrees1.getparent(i); /将s1,s2合并,则s1,s2的双亲是i huffTrees2.getparent(i); huffTrees1.geta(lchild); /s1是左孩子 huffTrees2.geta(rchild); /s2是右孩子 huffTreei.getweight(huffTrees1.returnweight()+huffTrees2.returnweight();/s1,s2的双亲的权值为s1,s2权值之和 void Select(elem
10、ent h,int k,int *a,int *b) /寻找最小和次小节点的序号 int i; int min1=1000; /初始化最小结点和次小结点 int min2=1000; for (i=0;i=k;i+)/找最小的结点序号 if (hi.parent=-1&hi.weightmin1) /如果没有父结点并且它的权值小于min1的权值 *a=i; /将i放入a中 min1=hi.weight; /找到第一个最小结点 for(i=0;i=k;i+) /找次小结点的序号 if(hi.parent=-1&(*a!=i)&hi.weightmin2) /满足没有父结点,此序号不等于最小结点的
11、序号,权值小于min2 *b=i; min2=hi.weight; /找到次最小结点 void HuffmanTreeCode(element HT) /字符编码 int i; char *temp; temp=(char *)malloc(n*sizeof(char); /分配n个字符空间 tempn-1=0; /最后一个字符以后结束字符串 int p; int s; for(i=0;in;i+) /n个字符结点一个个处理 p=i; s=n-1; /s为最后一个结点 while(HTp.parent!=-1) /从字符结点回溯,直至根结点 if(HTp.a=lchild) /p指向的如果是左
12、孩子 temp-s=0; /s位置字符为0 else if(HTp.a=rchild) /p指向的如果是右孩子 temp-s=1; /s位置字符为1 p=HTp.parent; /回溯父结点 HTi.code=(char *)malloc(n-s)*sizeof(char);/分配结点编码长度的内存空间 strcpy(HTi.code,temp+s); /将temp中从第s个位置开始,将编码拷贝到 HTi.code printf(%c,HTi.letter); printf(: ); printf(%sn,HTi.code); /打印出字符即对应的二进制字符串 file1HTi.letter
13、:HTi.code endl; /保存至编码文件中 void HuffmanTreeYima(element huff,char cod,int b) /译码 char sen100; char temp50; char voidstr= ; /空白字符串 int t=0; int s=0; int xx=0; for(int i=0 ; ib; i+) tempt+=codi; /读取字符 tempt = 0; /有效字符串 for(int j=0;jn;j+) /依次与所有字符编码开始匹配 if (!strcmp(huffj.code,temp) /匹配成功 sens=huffj.lett
14、er; /将字符保存到sen中 s+; xx+=t; strcpy(temp,voidstr); /将TEMP置空 t=0; /t置空 break; if(t=0) /t如果被置空了,表示都匹配出来了,打印译码 sens=0; cout译码为:endl; file2sen; coutsenendl; else /t如果没有被置空 , 源码无法被完全匹配 cout二进制源码有错!从第xx+1位开始endl; file2二进制源码有错!从第xx+1位开始endl; void main() char aLengh,p; int i,bLengh; int symbol=1; int x; int k
15、; if(!file1) cout不能打开文件1!; return; if(!file2) cout不能打开文件2!; return; couttttt哈夫曼编码与译码ttttendl; cout编码:endl; cout请输入一句话进行初始编码:; char buff1024=0;/零时存放输入的话 cin.getline(buff,1024);/读入一行包括空格键,以回车键结束 int len=strlen(buff); element hLengh; for (i=0;ilen;i+) for(int j=0;j=n) an=buffi; bn=1; n+; for (i=0;in;i+
16、) cout字符:(char)ai 权值:(int)biendl;/a存字符 b存权值; InitHuffmanTree(h,a,b); /哈夫曼树的初始化 HuffmanTreeCode(h); /编码 cout译码:endl; while(1) cout请输入要译码的二进制字符串,输入#结束:; file2p; if(p!=1&p!=0&p!=#) /若存在其它字符,x设为0,表示输入的不是二进制 x=0; codingk=p; if(p=#) symbol=0; /#号结束标志 else file2p; k+; if(x=1) file2endl译码为:; HuffmanTreeYima(h,coding,k-1); /进行译码 file2endl; else cout有非法字符!endl; file2endl有非法字符!endl; coutp; if(p=y|p=Y) continue; else break; file1.close (); file2.close ();.忽略此处.
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1