通信工程课程设计Word文件下载.docx
《通信工程课程设计Word文件下载.docx》由会员分享,可在线阅读,更多相关《通信工程课程设计Word文件下载.docx(27页珍藏版)》请在冰豆网上搜索。
但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码(复原).对于双工信道(既可以双向传输信息的信道),每端都需要一个完整的编/译码系统。
试为这样的信息收发站写一个哈夫曼的编/译码器。
该系统可进行字符与二进制码值间转换。
可用于电脑系统中用户的文件,这样可节省内存,当用户使用时又可转换为字符形式。
还可实现对所给文件进行统计字符出现频率,及相应二进制码值,并对文件编码解码。
1.
建立哈夫曼树:
从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树.
2.
编码:
利用已建立好的哈夫曼树,获得各个字符的哈夫曼编码,并对正文进行编码,然后保存编码结果至文件中。
3.
译码:
利用已建立好的哈夫曼树将文件中的编码进行译码获得原文件。
四、概要设计
1.系统结构图(功能模块图)
2.功能模块说明:
(1)统计各叶子节点的权值:
打开需要编码的文件,以字母为关键字,统计各字母出现的频率作为权值,记录并返回;
(2)建立哈夫曼树:
根据统计的权值,建立哈夫曼树的节点,总是从节点中选取权值最小和权值次小且双亲为0的两个节点加入到哈夫曼树中,复上述过程至所有权值均被选择过,便可建立一棵哈夫曼树;
(3)对所建哈夫曼树进行编码:
因权值所在的节点均是树的叶子节点,故从叶子节点开始向上推找其双亲节点,逆向求各叶子节点的编码,若该叶子节点是双亲的左孩子,则编码为‘0’,反之为‘1’,以此类推,便可得到每个叶子节点的哈夫曼编码,再利用已获得的各叶子的编码对原文件进行编码,并把编码存入文件中;
(4)译码:
根据文件中存放的编码从根节点开始,读取字符,字符为0走左,为1走右,直至找到叶子节点为止,以此得到译码,并把译码存入中.
五、详细设计及运行结果
1.计算权值:
2.建立哈夫曼树:
3.编码:
4.译码:
5.主函数:
6.部分运行结果:
六、调试情况,设计技巧及体会
整个程序设计过程中,程序模块的设计相对明朗一些,桌面设计较为简洁省去了没有必要在桌面现显示的操作项目,是整个程序明了易于操作。
然而
模块内部的联系比较紧密,关联程度高,且模块之间的值传递也比较简单,增加了程序的可读性,同时也便于调试。
不足之处在于自己目前所掌握的知识有限,在编写程序的过程中,所能用到的语言都较为简单,因此在设计算法时,有些地方设计的不是很好,如:
循环和判断条件是否满足的次数较多等;
时间复杂度较大,从而影响了程序的运行速度。
改进这一问题的方法就是掌握好C语言和数据结构的基础知识,平时应多写程序,并善于分析自己或他人的程序,找出每一个程序中的合理和不足之处,长期坚持下来的话,自己在编程方面的能力一点会大有提高的。
这一次做有关程序语言课程实习,遇到的主要问题不是前期的编码程序了,而是在调试过程,由于编写程序或录入程序时的粗心大意给后面的调试带来了很多问题:
C语言的使用不规范,有些习惯上的东西没有遵循导致有些细小的错误不易发现。
如:
字母‘O‘和数字‘0‘是不同类型的常量,在使用过程中没有细心地加以区别,导致一些错误;
又如:
一般在宏定义中使用大写字母,而我却用了小写,在后面的函数中,又用相同的字母定义了变量,导致程序无法正常运行,发现这易错误花费很长时间,这些本都是可以避免的。
因此编写程序的过程中一定要正确规范地使用C语言。
调试的过程之前都是在TC2.0的环境下进行的,这一次使用的是VisualC++6.0,刚开始的时候使用的不是很熟练,但经过几次的学习之后,目前已经可以很好地使用该工具了,同时也改变了以前遇到问题就问老师问同学,不自己先进行调试的不好的习惯。
在设计的过程中,老师和同学都给了很多的帮助,有时因一个问题和同学讨论花了很长的一段时间,但在问题解决了之后,我们都觉得时间花的值得,因为这些问题已经令我们印象深刻了。
通过此次一周半的课程设计,我对这学期所学的数据结构的知识有了更为深刻的认识,同时再一次使用C语言,使得上学期学的C语言的相关知识不被遗忘。
七、参考文献
1.《C语言程序设计》------科学出版社,王曙燕主编
2.《数据结构---C语言描述》---------高等教育出版社,耿国华主编
八、附录:
源代码
#include<
stdio.h>
string.h>
conio.h>
stdlib.h>
#defineMAX100
typedefstruct
{
intweight;
charx;
intp;
intlc,rc;
}Haffuman;
Haffumanr[2*MAX-1];
typedefstruct
ints;
charbits[MAX];
}ctype;
ctypecode[MAX];
charstring[MAX]={0};
chardata;
intfreq;
}NODE;
NODENode[MAX];
intk;
//用于统计所打开的文件的字符数
charfilename[30];
//要操作的文件数组
/***********字符个数统计函数**************************/
voidtongjihanshu()
chart;
charc;
FILE*fp;
printf("
请输入要进行操作的文件的名字以及储存路径:
\n"
);
gets(filename);
//输入文件名以及储存路径
fp=fopen(filename,"
rt"
if(fp==NULL)
{
printf("
打开文件失败,你所输入的件路径可能错误!
t=getch();
}
while((c=getc(fp))!
=EOF)
k++;
fclose(fp);
%d"
k);
}
//********************求取权值函数**********************
voidReadSourceFile()
charstr[MAX];
intj,i=0;
charl;
if((fp=fopen(filename,"
r"
))==NULL)
l=getch();
exit(0);
}
str[i]=fgetc(fp);
while(str[i]!
str[++i]=fgetc(fp);
str[i]='
\0'
;
for(j=0;
j<
MAX;
j++)
Node[j].data=0;
Node[j].freq=0;
}//对nod函数进行初初始化
Node[0].data=str[0];
Node[0].freq=1;
for(j=1;
=k;
j++)//对数组中的字符进行求权值////////////////////////////////////
for(i=0;
Node[i].data&
&
str[j]!
=Node[i].data;
i++)
;
Node[i].data=str[j];
Node[i].freq++;
//*****************************************************
intSethaffumanTree()/*建立哈夫曼树*/
/*typedefstruct
*/
intm1,m2,x1,x2,j,t;
inti=0,s=0;
while(Node[i].data)
r[i+1].weight=Node[i].freq;
r[i+1].x=Node[i].data;
r[i+1].p=0;
r[i+1].lc=0;
r[i+1].rc=0;
i++;
}//至此r[]的初始化完成
s=i;
//s得到所有的不同字符个数
i=0;
while(i<
s-1)
m1=32767;
m2=32767;
x1=0;
x2=0;
for(j=1;
=s+i;
if((r[j].weight<
m1)&
(r[j].p==0))//等于0表明没进树
{
m2=m1;
//m1用于放最小权值
x2=x1;
//x1,x2分别为r[]的下标
m1=r[j].weight;
//权值也随着赋予
x1=j;
}
else
if((r[j].weight<
m2)&
(r[j].p==0))
{
m2=r[j].weight;
//m2中放置次小权值
x2=j;
}
i++;
r[x1].p=s+i;
r[x2].p=s+i;
//次小和最小的双亲接点下标相同
r[s+i].weight=r[x1].weight+r[x2].weight;
r[s+i].lc=x1;
//左孩子的下标
r[s+i].rc=x2;
//右孩子的下标
r[s+i].p=0;
//双亲继续和其他接点相比较
t=2*s-1;
returnt;
//*********************************************************
voidHaffumanCode(intt)/*哈夫曼编码函数*/
inti,p,s,n,j,m;
ctypemd;
/*typedefstruct
*///用