题目利用二进制编码模拟信息的真实传输过程.docx

上传人:b****6 文档编号:16268377 上传时间:2023-07-12 格式:DOCX 页数:21 大小:21.86KB
下载 相关 举报
题目利用二进制编码模拟信息的真实传输过程.docx_第1页
第1页 / 共21页
题目利用二进制编码模拟信息的真实传输过程.docx_第2页
第2页 / 共21页
题目利用二进制编码模拟信息的真实传输过程.docx_第3页
第3页 / 共21页
题目利用二进制编码模拟信息的真实传输过程.docx_第4页
第4页 / 共21页
题目利用二进制编码模拟信息的真实传输过程.docx_第5页
第5页 / 共21页
题目利用二进制编码模拟信息的真实传输过程.docx_第6页
第6页 / 共21页
题目利用二进制编码模拟信息的真实传输过程.docx_第7页
第7页 / 共21页
题目利用二进制编码模拟信息的真实传输过程.docx_第8页
第8页 / 共21页
题目利用二进制编码模拟信息的真实传输过程.docx_第9页
第9页 / 共21页
题目利用二进制编码模拟信息的真实传输过程.docx_第10页
第10页 / 共21页
题目利用二进制编码模拟信息的真实传输过程.docx_第11页
第11页 / 共21页
题目利用二进制编码模拟信息的真实传输过程.docx_第12页
第12页 / 共21页
题目利用二进制编码模拟信息的真实传输过程.docx_第13页
第13页 / 共21页
题目利用二进制编码模拟信息的真实传输过程.docx_第14页
第14页 / 共21页
题目利用二进制编码模拟信息的真实传输过程.docx_第15页
第15页 / 共21页
题目利用二进制编码模拟信息的真实传输过程.docx_第16页
第16页 / 共21页
题目利用二进制编码模拟信息的真实传输过程.docx_第17页
第17页 / 共21页
题目利用二进制编码模拟信息的真实传输过程.docx_第18页
第18页 / 共21页
题目利用二进制编码模拟信息的真实传输过程.docx_第19页
第19页 / 共21页
题目利用二进制编码模拟信息的真实传输过程.docx_第20页
第20页 / 共21页
亲,该文档总共21页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

题目利用二进制编码模拟信息的真实传输过程.docx

《题目利用二进制编码模拟信息的真实传输过程.docx》由会员分享,可在线阅读,更多相关《题目利用二进制编码模拟信息的真实传输过程.docx(21页珍藏版)》请在冰点文库上搜索。

题目利用二进制编码模拟信息的真实传输过程.docx

题目利用二进制编码模拟信息的真实传输过程

题目:

利用二进制编码模拟信息的真实传输过程

哈夫曼编/译码器

姓名:

宋力完成日期:

11.2

一.需求分析

1.进行快速远距离通信的主要手段是电报,即将需传送的文字转换成二进制字符串

2.本程序的目的是解决通信过程中的编码和译码问题

3.程序中传输的是二进制“字符串”(实际每个字符占8位),这只是模拟真实传输的过程

4.测试数据可由用户输入

5.说明:

编码和译码程序是分开进行的,因此,具有一定的实用性。

比如:

我用编码器输入一段字符串,然后将编码后的二进制文本(只含0与1)发送到对方,对方接收到该文本后,用译码器进行译码,可以还原出最初输入的字符串。

无须输入权值,程序将会自行统计字母信息和权值信息

二.概要设计

注意:

传输过程中的是二进制编码而不包括任何其他的字符,因此编码时有必要先将一些有用的信息(如:

字母)转换为二进制存储起来

编码器和译码器分处两个程序中:

A.编码器

编码器程序的主要操作包括:

1.字符串输入和求哈夫曼编码

(1)用户输入一串字符串

(2)程序自行统计出字符串中字符的种类和各字符出现的次数(即权值)

(3)用哈夫曼树对以上出现的字符按权值大小进行编码

2.生成二进制的需要传输的字符串(包括字符信息和附加信息)

(1)设要传输的字符串为char*ok,分别将以下信息包含到ok中

a.出现字符种类的个数

b.字母对应ASC码转化为二进制后的编码

c.字母之间的分隔标记00000001

d.输入的字符串转化后的二进制字符串

(2)将包含以上信息的串ok存入文件(“字符串的二进制编码.txt”)中

B.译码器

译码器的主要操作包括:

1.接收文本中的二进制字符串

2.对字符串进行翻译,译码得到相应的字母

3.译码得到一串字符串

4.将得到字符串并将其输入到文本("字符串的二进制编码.txt")中

5.打开文本比较文本中的字符串,发现译出的字符串与原来输入的字符串相同

该程序用到的抽象数据类型

ADThufffmantree

{

数据对象:

D={ai|ai∈字母字符集,i=1,2,3……,n,n>=0}

数据关系:

R1={|ai-1,ai∈D,i=2,3,……,n}

基本操作:

voidcode(char*p,int*&w,char*&m,int&n)

初始条件:

p为一个字符串

操作结果:

生成值,用w存放权值,用m存放出现的字符,用n存放字符的个数

且最后生成一文本保存得到的编码字符串

}

以下是我程序设计的伪码:

1:

编码器

结构体:

typedefstruct权值

{charc;

intweight;

}cell,*good;

typedefstruct哈夫曼树

{

intweight;

intparent,lchild,rchild;

};

intminimum(HuffmanTreetree,inti)

初始条件:

存在哈夫曼树(可以为空)

操作结果:

返回权值最小的根结点

voidfind(HuffmanTreet,inti,int*s1,int*s2)

初始条件:

存在哈夫曼树

操作结果:

在i个结点中选择2个权值最小的树的根结点序号,s1为其中序号小的那个

voidHuffmanCoding(HuffmanTree*HT,HuffmanCode*HC,int*&w,intn)

初始条件:

HC为指向各字符哈夫曼编码的指针,哈夫曼树存在,w存放权值

操作结果:

w保存了权值,对哈夫曼树进行了编码,保存在HC中

intsearch(chara,char*m,intz)

初始条件:

m为指向字符的指针,a为要判断的字符

操作结果:

查找m中是否出现过字符a,有则返回它的下标,没有则返回-1

voidcode(char*p,int*&w,char*&m,int&n)

初始条件:

w用来存放各字符的权值,p为指向存放字符串指针,n为字符种类树目

操作结果:

w存放了各字符的权值,将指定的字符串进行了编码,并将二进制编码保存到了文件中,另一个文件存放原始字符串

voidmain()

{

输入信息和文件初始化,字母的权值将在后面进行统计

将字符串信息写入文件中

打开文本,用直观的形式观察输入的字符串

编码函数(包括计算权值,各输入字符的哈夫曼编码和最后将要传输的二进制编码)

将编码得到的二进制串保存到另一个文件中

}

2:

译码器

intchange(intx)

操作结果:

八位以下的伪十进制数转化为真十进制数

voidtranslate(char*s)

初始条件:

指向二进制字符串的指针s

操作结果:

进行译码操作,得到字符串,并将它一文本形式输出,可将其与原始字符串进行比较

voidmain()

{

输入信息和文件初始化

读入二进制编码文件,并用字符指针指向二进制字符串

打开读入的二进制文本文档,以直观的形式观察该二进制字符串

进行译码操作

输出最后译码后的文本文档

}

三.详细设计

1.编码程序

//运行正常!

#include"stdlib.h"

#include"stdio.h"

#include"string.h"

#include"iostream.h"

////////////////////////////////

typedefstruct//存放权值字母的结构体

{

charc;

intweight;

}cell,*good;

///////////////////////////////

////////////////////////////////

typedefstruct//哈夫曼树结构体

{

intweight;

intparent,lchild,rchild;

}HTNode,*HuffmanTree;

////////////////////////////////////

typedefchar**HuffmanCode;//存放哈夫曼编码的二级指针

///////////////////////////////////

intminimum(HuffmanTreetree,inti)

{//返回权值最小的树的根结点

intj,tag;

intk=10000;

for(j=1;j<=i;j++)

if(tree[j].weight

k=tree[j].weight,tag=j;

tree[tag].parent=1;//根结点的双亲赋1

returntag;

}

////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////

voidfind(HuffmanTreet,inti,int*s1,int*s2)

{//在i个结点中选择2个权值最小的树的根结点序号,s1为其中序号小的那个

intj;

*s1=minimum(t,i);

*s2=minimum(t,i);

if(*s1>*s2)

{

j=*s1;

*s1=*s2;

*s2=j;

}

}

//////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////

voidHuffmanCoding(HuffmanTree*HT,HuffmanCode*HC,int*&w,intn)//求字符的赫夫曼编码HC

{//w存放n个字符的权值(均>0),HT为构造的赫夫曼树

HuffmanTreehfm;

char*cd;

intm=2*n-1;

*HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));/*0号单元未用*/

inti;

/////////////////////////////////////////初始化

for(hfm=*HT+1,i=1;i<=n;++i,++hfm,++w)

{

(*hfm).weight=*w;

(*hfm).parent=0;

(*hfm).lchild=0;

(*hfm).rchild=0;

}

for(;i<=m;++i,++hfm)

(*hfm).parent=0;

//////////////////////////////////////////

*HC=(HuffmanCode)malloc((n+1)*sizeof(char*));//堆首暂不使用

ints1,s2;

for(i=n+1;i<=m;++i)//建哈夫曼树

{

find(*HT,i-1,&s1,&s2);

(*HT)[s1].parent=(*HT)[s2].parent=i;

(*HT)[i].lchild=s1;

(*HT)[i].rchild=s2;

(*HT)[i].weight=(*HT)[s2].weight+(*HT)[s1].weight;

}

//////////////////////////////////////////////////根反向求字符的赫夫曼编码

intx,start;

intk;

cd=(char*)malloc(n*sizeof(char));

cd[n-1]='\0';//串尾结束符号

for(i=1;i<=n;i++)

{//求每个字符的赫夫曼编码

start=n-1;//存放编码终止的位置

for(x=i,k=(*HT)[i].parent;k!

=0;x=k,k=(*HT)[k].parent)

if((*HT)[k].lchild==x)

cd[--start]='0';

else

cd[--start]='1';

(*HC)[i]=(char*)malloc((n-start)*sizeof(char));//分配堆空间

strcpy((*HC)[i],&cd[start]);

}

free(cd);//释放堆空间

}

//查找m中是否出现过字符a,有则返回它的下标,没有则返回-1

intsearch(chara,char*m,intz)

{

intj=0;

while(j

{

if(m[j]==a)

returnj;//有就返回它在m或者w中的下标(w,m中一样)

j++;

}

return-1;//没有就返回-1

}

//////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////

/*生成将要发送的二进制字符串:

包括字符种类数,字符的ASCII码,字符的哈夫曼代码,间隔标记符,哈夫曼编码串*/

voidcode(char*p,int*&w,char*&m,int&n)//进行编码

{

///////////////////////////////////////////////////////////以下代码求权值

m=(char*)malloc(sizeof(char));//生成堆空间存放出现的字母

w=(int*)malloc(sizeof(int));//存放字母对应的权值,其下标与上面m下标对应

inti=0,k,z=1;

while(*(p+i)!

='\0')

{

if(z==1)//k==-1用于后面if语句的条件判断,表示没有出现

k=-1;

else

k=search(*(p+i),m,z);//查找,若出现字符m则返回其下标,否则返回-1(表示没有)

if(k==-1)//如果没有就加入该字符

{z++;

m=(char*)realloc(m,z*sizeof(char));

w=(int*)realloc(w,z*sizeof(int));//w存放对应字符的权值

m[z-2]=*(p+i);

m[z-1]='\0';//最后一个赋'\0'

w[z-2]=1;//对应权值赋1

}

else//有就在权值上加1

w[k]++;

i++;

}

n=z-2;//共n+1个字符(不包括\0),序号0—n,第n+1为\0

cout<<"字符"<<""<<"权值"<

for(intl=0;l

cout<

//////////////////////////////////////////////////////////构建哈夫曼树

HuffmanTreeHT;

HuffmanCodeHC;

HuffmanCoding(&HT,&HC,w,n+1);//调用哈夫曼编码的函数

intzz,length,totle;//下标

char*t;//后面用来存放核心字符串编码

i=1;

totle=strlen(HC[1])+1;

t=(char*)malloc(totle*sizeof(char));

t[0]='\0';

strcpy(t,HC[1]);

while(*(p+i)!

='\0')

{

zz=search(*(p+i),m,n+2);

length=strlen(HC[zz+1]);

totle+=length;

t=(char*)realloc(t,totle*sizeof(char));

strcat(t,HC[zz+1]);//将字符编码串连接到原来的后面

i++;

}

//////////////////////////////////////////////////////存放字符种类数

char*ok=(char*)malloc(16*sizeof(char));

ok[0]='\0';

char*guodu=(char*)malloc(8*sizeof(char));//中间变量指针

guodu[0]='\0';//存放字母

itoa(n+1,ok,2);//字符种类个数存入,ok后面还有几个小空间未用!

strcat(ok,"00000001");

////////////////////////////////////////////////存放字母的ASC码对应二进制字符串

intn1=16;//表示ok现在存放的字符串长度

for(i=0;i

{

itoa(m[i],guodu,2);//字母转化为二进制然后存入guodu中

ok=(char*)realloc(ok,(n1+strlen(guodu)+8)*sizeof(char));//////////

n1+=strlen(guodu)+8;//////////

strcat(ok,guodu);//输入字母代码

strcat(ok,"00000001");//字母之间用00000001隔开

}

free(guodu);//释放堆空间

/////////////////////////////////////////////////存放哈夫曼码

for(i=0;i

{

ok=(char*)realloc(ok,(n1+strlen(HC[i+1])+8)*sizeof(char));/////////////

n1+=strlen(HC[i+1])+8;

strcat(ok,HC[i+1]);//输入单字符对应的编码(编码出错了)

strcat(ok,"00000001");//要改进,用第一个编码来间隔,前面对应加入该码长度

}

/////////////////////////////////////////////////存放字符串哈夫曼编码

ok=(char*)realloc(ok,n1+strlen(t)*sizeof(char));

strcat(ok,t);//输入字符串编码

////////////////////////////////////////////////写入文件

FILE*fp;

if((fp=fopen("字符串的二进制编码.txt","wt+"))==NULL)

{

printf("error!

");

exit(-1);

}

fwrite(ok,strlen(ok)+1,1,fp);

fclose(fp);

free(ok);//释放堆空间

}

/////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////

voidmain()

{

int*w,n;

char*m;//存放出现字符的字符串

charp[256];//存入输入的字符串(若为文件则可指向它)

printf("请输入一串字符串:

");

gets(p);//输入要传输的字符串,字母的权值将在后面进行统计

FILE*fp3;//新建文本文件,并对其操作

if((fp3=fopen("输入的(要进行传输的)字符串.txt","wt+"))==NULL)

{

printf("error!

");

exit(-1);

}

fwrite(p,sizeof(char),strlen(p)+1,fp3);

fclose(fp3);

system("输入的(要进行传输的)字符串.txt");//打开该文本文件

code(p,w,m,n);//编码函数

2.//译码程序

//接受文档中二进制的字符串,并将其译码,得到一串字符串

//运行正常

#include"stdlib.h"

#include"stdio.h"

#include"string.h"

#include"iostream.h"

//////////////////////////////////

intchange(intx)//八位以下的伪十进制数转化为真十进制数

{

inti,y=0,j=1,k=1;

if(x>11111111)//超过8位就退出

exit(-1);

for(i=0;i<8;i++)//求十进制数,用y表示

{

y+=k*((x/j)%10);

j=j*10;

k=2*k;

}

returny;

}

////////////////////////////////////

////////////////////////////////////

voidtranslate(char*s)

{

inti=0,j=0,z;

char*mark1,*mark2,*flag;//均为标记指针

char*tchar;//存放字母

intn;

flag=s;

char*mid="00000001";//分隔符号

mark1=strstr(s,mid);//找标记的首地址

while((flag+j)!

=mark1)//累计当前地址到标记地址间的字符个数

j++;

char*ctemp;

////////////////////////////////////////////////////////

//////////////////////////////////////译出字符的种类数

ctemp=(char*)malloc((j+1)*sizeof(char));//开辟堆空间

for(i=0;i

ctemp[i]=flag[i];

ctemp[j]='\0';

n=atoi(ctemp);//二进制整数(字符个数)

n=change(n);//字符的种类数

//////////////////////////////////////////////////////

////////////////////////////////////////译出出现的字符

tchar=(char*)malloc((n+1)*sizeof(char));//存放字符

char**bm=(char**)malloc(n*sizeof(char*));//存放小编码指针

for(z=0;z

{j=0;

mark2=mark1+8;//00000001后标记

flag=mark2;

mark1=strstr(mark2,mid);//找标记的首地址

while((mark2+j)!

=mark1)

j++;

free(ctemp);//释放堆空间

ctemp=(char*)malloc((j+1)*sizeof(char));//再次开辟空间

for(i=0;i

ctemp[i]=flag[i];//求表示字母ASCII码的二进制编码串

ctemp[j]='\0';

tchar[z]=(char)change(atoi(ctemp));//译出的字母存入数组中

}

//mark1此时指向00000001前了

///////////////////////////////////////////////////////

//////////////////////////////////

char*temp;

for(z=0;z

{

j=0;

mark2=mark1+8;//让mark2指向标记后

flag=mark2;

mark1=strstr(mark2,mid);//找标记的首地址

if(mark1==mark2)//当编码为分隔标记符时另外考虑

{mark1+=8;

mark1=st

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 工作范文 > 行政公文

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2