1、数据结构设计说明和代码数据结构设计大赛作品说明书作品名称: 译 码 器 院 系: 计算机科学与信息工程学院 学生姓名: 李 瑞 琳 学 号: 200903060016 专业班级: 09级网络工程(二)班 指导教师: 闫 怀 平 年 05月 20日一、 作品的背景 【说明设计该作品的目的,或者说作品能够解决什么实际问题】目前,进行远距离快速通信的主要手段是电报,即将需传送的文字转换成由二进制的字符组成的字符串,并且让传送的文件中次数较多的字符采用尽可能短, 以及译码后所得到的译码文件唯一。另外,当今的密码学就是在编码与译码的斗争中发展起来的,成为一门综合行的尖端技术科学,为此,做了如下的具体算法
2、实现。1.解决的实际问题:读取要编码的文本文件,将文件的内容进行编码,生成新的文件。对编码文件进行解码,获得文本文件。2.要求:将输入的文件进行编码,得到相应的密码序列。将译码的文本文件和原文件进行比较,恢复文件和原文件必须完全一致。二、设计思路 【说明为了解决实际的问题,采用什么样的数据和算法】1.采用的数据如下:设字符集及频度如下表:字符空格ABCDEFGHIJKLM频度1866413223210321154757153220字符NOPQRSTUVWXYZ频度57631514851802381811612.采用算法如下:采用Huffman编码思想实现对字符串的编码,以及对编码的解码。对上述
3、表格中的27个字符分别编码(为便于输入,空格在程序实现过程中用*代替),其实现算法是建立赫夫曼树HC,对每一个字符进行编码,并将由赫夫曼树所得到的编码串存储在HC中。建立编码、译码函数,对输入的文件或密码进行转换,再通过main()函数的调用,将其进行输出。二、 程序主要方法说明 【说明主要方法的功能和实现细路以及技巧,只要方法的声明,不要贴实现代码】 实现思路:建立如图所示的赫夫曼树(赫弗曼树的形式不唯一),并编码1000100603397110211186355248空格111000182173128120103108111100000E1636478102519580645757ONI1
4、110000TSA104847534335323249111000HRLD0232018173122282111100WUMFC10981615151310YVPGB541100K221111ZXQJHT初态: HT终态:HTHTweightparentlchildrchildweightparentlchildrchild11860001186510026400026445003130003133300422000422380053200053239006103000610348007210007213700815000815330094700094741001057000105743001
5、110001112800125000125310013320001332390014200001420360015570001557440016630001663440017150001715340018100018128001948000194841002051000205143002180000218047002223000222336002380002383200241800024183500251000251290026160002616340027100027129002800028230111829000292302527300003043128293100031932301232
6、000321735233133000332837383400034313817263500035354032243600036434014223700037494273338000385342434390003964455134000040784635364100041954691942000421024737384300043108482010440004412049151645000451284923946000461735040414700047182502142480004821151643490004924852444550000503555246475100051397531485
7、200052603534950530005310000515210011100101011111000011110000100001111000111101111110001010110111110111101011010111111010100000HC123456789101112131415161718192021222324252627110000100111000010100110111011001111000001100011111111110000101111011 具体算法如下所示:1. 赫夫曼树和赫夫曼编码的存储结构表示typedef structint weight,par
8、ent,lchild,rchild;HTNode,*HuffmanTree;/动态分配数组存储赫夫曼树typedef char *HuffmanCode;/动态分配数组存储赫夫曼编码表2. 定义全局变量:用于存储需要编码的字符集数组node29用于存储需要编码的文件数组strMAX1用于存储密码文件的数组NfileMAX2建立相应的实现函数:用于建立赫夫曼树函数HuffmanCoding(&HT, &HC, *w, n)实现建立赫夫曼树的选择函数 Select(HT, k, &m1, &m2)实现对文件编码的编码函数Decode(HC)实现对密码译码的译码函数Coding(HT, HC) 对以
9、上函数进行调用的主函数main()出错判断响应A当输入文本错误时,提出错误提醒printf(第%d个字符输入错误!请重新输入:,j+1);B当选择执行的选项出错时,提出错误提醒printf(输入错误,请重新输入);三、 程序测试说明 【为了验证程序满足设计要求,需要给出适当的测试数据。如输入什么数据,程序能够输出什么数据。要求至少给出3组以上测试数据,并说明每组测试数据能够测试作品的什么功能】程序中输入及输出数据的运行步骤如下所示:步骤一:编译并运行程序,按提示运行(例如,“按回车键,继续”)已验证所得赫弗曼树及27个字符的编码是否与分析的一致结果如下:步骤二:输入选择0-2以外的数,如3,以
10、测试出错相应功能:当选择执行的选项出错时,程序给出错误提醒。得出如下结果:步骤三:输入文本文件“ROME*WAS*NOT*BUILT*IN*A*DAY”,并在程序执行前将存储密码文件的数组初始化如下: NfileMAX2=1,1,0,1,1,1,0,0,1,1,1,0,0,1,0,0,1,0,0,0,1,1,0, 0,0,1, 1,0,1,0,0,1,1,0,0,0,1,0,0,0,1,0,0,1,1,1,1,0,0,0,1,1,1,1,0,1,0, 1,1,0,0,1,1,0,1,1,1,1,0,1,1,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0, 1,0,1,0,0
11、,0,1,0,1,1,0,1,0,1,0,1,1,1,1,1,1,1测试译码的文本文件和原文件进行比较,恢复文件和原文件是否完全一致步骤四:输入文本文件“TiME*is*MonEY”,测试错误判断响应当输入文本错误时,提出错误提醒printf(第%d个字符输入错误!请重新输入:,j+1);步骤五:输入正式文本文件“THANK*YOU*FOU*YOUR*LETTER*CONVEYING*ON*MY*APPOINTMENT*I*WISH*YOU*SUCCESS*AND*FULFILLMENT*THE*YEARS*AHEAD”得出相应密码文件:步骤六:选择“0”,返回,结束程序。程序代码:#incl
12、ude #include #include #define MAX1 3000#define MAX2 110#define OK 1#define ERROR 0typedef int Status;typedef structint weight,parent,lchild,rchild;HTNode,*HuffmanTree;/动态分配数组存储赫夫曼树typedef char *HuffmanCode;/动态分配数组存储赫夫曼编码表char node29=*ABCDEFGHIGKLMNOPQRSTUVWXYZ;/定义字符集int n=27;/需要编码的字符总数int m=2*n-1;/赫
13、夫曼编码表HT的长度int count=0;/记录输入的密码数字的个数char strMAX1;/定义存储需要编码的文件数组int NfileMAX2=1,1,0,1,1,1,0,0,1,1,1,0,0,1,0,0,1,0,0,0,1,1,0, 0,0,1, 1,0,1,0,0,1,1,0,0,0,1,0,0,0,1,0,0,1,1,1,1,0,0,0,1,1,1,1,0,1,0, 1,1,0,0,1,1,0,1,1,1,1,0,1,1,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0, 1,0,1,0,0,0,1,0,1,1,0,1,0,1,0,1,1,1,1,1,1,1;
14、/定义密码文件数组void Select(HuffmanTree HT, int k, int &m1, int &m2) int i,min1,min2; min1=min2=10000;/首先给它们赋一个最大的值,这个值大于所有可能的权值 m1=1,m2=1; for(i=1;i=k;i+) if( HTi.weightmin1 & HTi.parent=0 ) min1=HTi.weight;m2=m1;m1=i; else if( HTi.weight 0),构造赫夫曼树HT, / 并求出n个字符的赫夫曼编码HC int i, j, s1, s2, start; char *cd; i
15、nt c, f; if (n=1) return; HT = (HuffmanTree)malloc(m+1) * sizeof(HTNode); / 0号单元未用 for (i=1; i=n; i+) /初始化 HTi.weight=wi-1; HTi.parent=0; HTi.lchild=0; HTi.rchild=0; for (i=n+1; i=m; i+) /初始化 HTi.weight=0; HTi.parent=0; HTi.lchild=0; HTi.rchild=0; printf(n赫夫曼树的构造,初态如下所示:n); printf(HT初态:n 结点 weight p
16、arent lchild rchild); for (i=1; i=m; i+) printf(n%6d%10d%10d%10d%10d,i,HTi.weight, HTi.parent,HTi.lchild, HTi.rchild); printf( 按回车键,继续 .); getchar(); for (i=n+1; i=m; i+) / 建赫夫曼树 / 在HT1.i-1中选择parent为0且weight最小的两个结点, / 其序号分别为s1和s2。 Select(HT, i-1, s1, s2); HTs1.parent = i; HTs2.parent = i; HTi.lchild
17、 = s1; HTi.rchild = s2; HTi.weight = HTs1.weight + HTs2.weight; printf(n构造的赫夫曼树如下:n); printf( 结点 weight parent lchild rchild); for (j=1; j=m; j+) printf(n%6d%10d%10d%10d%10d,j,HTj.weight, HTj.parent,HTj.lchild, HTj.rchild); printf( 按回车键,继续 .); getchar(); /- 从叶子到根逆向求每个字符的赫夫曼编码 - HC=(HuffmanCode)mallo
18、c(n+1)*sizeof(char *); cd = (char *)malloc(n*sizeof(char); / 分配求编码的工作空间 cdn-1 = 0; / 编码结束符。 for (i=1; i=n; +i) / 逐个字符求赫夫曼编码 start = n-1; / 编码结束符位置 for (c=i, f=HTi.parent; f!=0; c=f, f=HTf.parent) / 从叶子到根逆向求编码 if (HTf.lchild=c) cd-start = 0; else cd-start = 1; HCi = (char *)malloc(n-start)*sizeof(cha
19、r); / 为第i个字符编码分配空间 strcpy(HCi, &cdstart); / 从cd复制编码(串)到HC free(cd); / 释放工作空间 /outputcoding for(i=1;i=n;i+) printf(字符%c:%sn,nodei-1,HCi); printf(n); / HuffmanCodingint Decode(HuffmanCode HC)/编码 int j,L; printf(请输入文本:n); scanf(%s,str);getchar(); L=strlen(str);/求字符串的长度 printf(文本字符个数为:); printf(%d,L); p
20、rintf(n); for(j=0;j=A&strj=Z)|(strj=*) printf(第%d个字符输入错误!请重新输入:,j+1); strj=getchar();getchar(); printf(n); printf(文本的编码如下:n); j=0; while(strj!=0) for(int i=0;i27;i+) if(strj=nodei) printf(%s,HCi+1); j+; printf(n); return OK;void Coding(HuffmanTree HT,HuffmanCode HC)/译码 int j=0; int t; while(jcount)
21、t=m; while(HTt.lchild!=0|HTt.rchild!=0) if(Nfilej=0) t=HTt.lchild; else t=HTt.rchild; j+; printf(%c,nodet-1); void main() int k=1; int n=27; HuffmanTree HT; HuffmanCode HC; int w=186,64,13,22,32,103,21,15,47,57,1,5,32,20, 57,63,15,1,48,51,80,23,8,18,1,16,1;/各个需要编码字符的频度,即赫弗曼树结点的权值 HuffmanCoding(HT,HC
22、,w,n); while(k) printf(n); printf( 欢迎进入编码、译码系统n); printf(*n); printf( 1.编码 n); printf( 2.译码 n); printf( 0.返回 n); printf(*n); printf( 请选择(0-2):); scanf(%d,&n); getchar(); switch(n) case 1: Decode(HC);break; case 2: printf(密码文件如下:n); for(int i=0;iMAX2;i+)/输出密码文件数组中的元素 printf(%d,Nfilei); count+; printf(n); printf(原文本如下:n); Coding(HT,HC); break; case 0:m=0;break; default:printf(输入错误,请重新输入);break;
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1