西安电子科技大学信息论与编码作业.docx

上传人:b****6 文档编号:8455638 上传时间:2023-01-31 格式:DOCX 页数:24 大小:310.68KB
下载 相关 举报
西安电子科技大学信息论与编码作业.docx_第1页
第1页 / 共24页
西安电子科技大学信息论与编码作业.docx_第2页
第2页 / 共24页
西安电子科技大学信息论与编码作业.docx_第3页
第3页 / 共24页
西安电子科技大学信息论与编码作业.docx_第4页
第4页 / 共24页
西安电子科技大学信息论与编码作业.docx_第5页
第5页 / 共24页
点击查看更多>>
下载资源
资源描述

西安电子科技大学信息论与编码作业.docx

《西安电子科技大学信息论与编码作业.docx》由会员分享,可在线阅读,更多相关《西安电子科技大学信息论与编码作业.docx(24页珍藏版)》请在冰豆网上搜索。

西安电子科技大学信息论与编码作业.docx

西安电子科技大学信息论与编码作业

Huffman

#include

#include

#include

#include

#include

//typedefintTElemType;

constintUINT_MAX=1000;

charstr[50];

typedefstruct

{

intweight,K;

intparent,lchild,rchild;

}HTNode,*HuffmanTree;

typedefchar**HuffmanCode;

//-----------全局变量-----------------------

HuffmanTreeHT;

HuffmanCodeHC;

intw[50],i,j,n;

charz[50];

intflag=0;

intnumb=0;

//-----------------求哈夫曼编码-----------------------

structcou{

chardata;

intcount;

}cou[50];

intmin(HuffmanTreet,inti)

{//函数voidselect()调用

intj,flag;

intk=UINT_MAX;//取k为不小于可能的值,即k为最大的权值1000

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

if(t[j].weight

k=t[j].weight,flag=j;

t[flag].parent=1;

returnflag;

}

//--------------------slect函数----------------------

voidselect(HuffmanTreet,inti,int&s1,int&s2)

{//s1为最小的两个值中序号小的那个

intj;

s1=min(t,i);

s2=min(t,i);

if(s1>s2)

{

j=s1;

s1=s2;

s2=j;

}

}

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

{//w存放n个字符的权值(均>0),构造哈夫曼树HT,并求出n个字符的哈夫曼编码HC

intm,i,s1,s2,start;

//unsignedc,f;

intc,f;

HuffmanTreep;

char*cd;

if(n<=1)

return;//检测结点数是否可以构成树

m=2*n-1;

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

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

{

p->weight=*w;

p->parent=0;

p->lchild=0;

p->rchild=0;

}

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

p->parent=0;

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

{//在HT[1~i-1]中选择parent为0且weight最小的两个结点,其序号分别为s1和s2

select(HT,i-1,s1,s2);

HT[s1].parent=HT[s2].parent=i;

HT[i].lchild=s1;

HT[i].rchild=s2;

HT[i].weight=HT[s1].weight+HT[s2].weight;

}

//从叶子到根逆向求每个字符的哈夫曼编码

HC=(HuffmanCode)malloc((n+1)*sizeof(char*));

//分配n个字符编码的头指针向量([0]不用)

cd=(char*)malloc(n*sizeof(char));//分配求编码的工作空间

cd[n-1]='\0';//编码结束符

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

{//逐个字符求哈夫曼编码

start=n-1;//编码结束符位置

for(c=i,f=HT[i].parent;f!

=0;c=f,f=HT[f].parent)

//从叶子到根逆向求编码

if(HT[f].lchild==c)

cd[--start]='0';

else

cd[--start]='1';

HC[i]=(char*)malloc((n-start)*sizeof(char));

//为第i个字符编码分配空间

strcpy(HC[i],&cd[start]);//从cd复制编码(串)到HC

}

free(cd);//释放工作空间

}

//---------------------获取报文并写入文件---------------------------------

intInputCode()

{

//cout<<"请输入你想要编码的字符"<

FILE*tobetran;

if((tobetran=fopen("tobetran.txt","w"))==NULL)

{

cout<<"不能打开文件"<

return0;

}

cout<<"请输入你想要编码的字符"<

gets(str);

fputs(str,tobetran);

cout<<"获取报文成功"<

fclose(tobetran);

returnstrlen(str);

}

//--------------初始化哈夫曼链表---------------------------------

voidInitialization()

{inta,k,flag,len;

a=0;

len=InputCode();

for(i=0;i

{k=0;flag=1;

cou[i-a].data=str[i];

cou[i-a].count=1;

while(i>k)

{

if(str[i]==str[k])

{

a++;

flag=0;

}

k++;

if(flag==0)

break;

}

if(flag)

{

for(j=i+1;j

{if(str[i]==str[j])

++cou[i-a].count;}

}

}

n=len-a;

for(i=0;i

{cout<

cout<

}

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

{*(z+i)=cou[i].data;

*(w+i)=cou[i].count;

}

HuffmanCoding(HT,HC,w,n);

//------------------------打印编码-------------------------------------------

cout<<"字符对应的编码为:

"<

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

{

puts(HC[i]);

}

//--------------------------将哈夫曼编码写入文件------------------------

cout<<"下面将哈夫曼编码写入文件"<

FILE*htmTree;

charr[]={'','\0'};

if((htmTree=fopen("htmTree.txt","w"))==NULL)

{

cout<<"cannotopenfile"<

return;

}

fputs(z,htmTree);

for(i=0;i

{

fprintf(htmTree,"%6d",*(w+i));

fputs(r,htmTree);

}

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

{

fputs(HC[i],htmTree);

fputs(r,htmTree);

}

fclose(htmTree);

cout<<"已将字符与对应编码写入根目录下文件htmTree.txt中"<

}

//---------------------编码函数---------------------------------

voidEncoding()

{

cout<<"下面对目录下文件tobetran.txt中的字符进行编码"<

FILE*tobetran,*codefile;

if((tobetran=fopen("tobetran.txt","rb"))==NULL)

{

cout<<"不能打开文件"<

}

if((codefile=fopen("codefile.txt","wb"))==NULL)

{

cout<<"不能打开文件"<

}

char*tran;

i=99;

tran=(char*)malloc(100*sizeof(char));

while(i==99)

{

if(fgets(tran,100,tobetran)==NULL)

{

cout<<"不能打开文件"<

break;

}

for(i=0;*(tran+i)!

='\0';i++)

{

for(j=0;j<=n;j++)

{

if(*(z+j-1)==*(tran+i))

{

fputs(HC[j],codefile);

if(j>n)

{

cout<<"字符错误,无法编码!

"<

break;

}

}

}

}

}

cout<<"编码工作完成"<

fclose(tobetran);

fclose(codefile);

free(tran);

}

//-----------------译码函数---------------------------------

voidDecoding()

{

cout<<"下面对根目录下文件codefile.txt中的字符进行译码"<

FILE*codef,*txtfile;

if((txtfile=fopen("txtfile.txt","w"))==NULL)

{

cout<<"不能打开文件"<

}

if((codef=fopen("codefile.txt","r"))==NULL)

{

cout<<"不能打开文件"<

}

char*work,*work2,i2;

inti4=0,i,i3;

unsignedlonglength=10000;

work=(char*)malloc(length*sizeof(char));

fgets(work,length,codef);

work2=(char*)malloc(length*sizeof(char));

i3=2*n-1;

for(i=0;*(work+i-1)!

='\0';i++)

{

i2=*(work+i);

if(HT[i3].lchild==0)

{

*(work2+i4)=*(z+i3-1);

i4++;

i3=2*n-1;

i--;

}

elseif(i2=='0')i3=HT[i3].lchild;

elseif(i2=='1')i3=HT[i3].rchild;

}

*(work2+i4)='\0';

fputs(work2,txtfile);

cout<<"译码完成"<

free(work);

free(work2);

fclose(txtfile);

fclose(codef);

}

//-----------------------打印编码的函数----------------------

voidCode_printing()

{

cout<<"下面打印根目录下文件CodePrin.txt中编码字符"<

FILE*CodePrin,*codefile;

if((CodePrin=fopen("CodePrin.txt","w"))==NULL)

{

cout<<"不能打开文件"<

return;

}

if((codefile=fopen("codefile.txt","r"))==NULL)

{

cout<<"不能打开文件"<

return;

}

char*work3;

work3=(char*)malloc(51*sizeof(char));

do

{

if(fgets(work3,51,codefile)==NULL)

{

cout<<"不能读取文件"<

break;

}

fputs(work3,CodePrin);

puts(work3);

}while(strlen(work3)==50);

free(work3);

cout<<"打印工作结束"<

fclose(CodePrin);

fclose(codefile);

}

//-------------------------------打印译码函数---------------------------------------------

voidCode_printing1()

{

cout<<"下面打印根目录下文件txtfile.txt中译码字符"<

FILE*CodePrin1,*txtfile;

if((CodePrin1=fopen("CodePrin1.txt","w"))==NULL)

{

cout<<"不能打开文件"<

return;

}

if((txtfile=fopen("txtfile.txt","r"))==NULL)

{

cout<<"不能打开文件"<

return;

}

char*work5;

work5=(char*)malloc(51*sizeof(char));

do

{

if(fgets(work5,51,txtfile)==NULL)

{

cout<<"不能读取文件"<

break;

}

fputs(work5,CodePrin1);

puts(work5);

}while(strlen(work5)==50);

free(work5);

cout<<"打印工作结束"<

fclose(CodePrin1);

fclose(txtfile);

}

//------------------------打印哈夫曼树的函数-----------------------

voidcoprint(HuffmanTreestart,HuffmanTreeHT)

{

if(start!

=HT)

{

FILE*TreePrint;

if((TreePrint=fopen("TreePrint.txt","a"))==NULL)

{cout<<"创建文件失败"<

return;

}

numb++;//该变量为已被声明为全局变量

coprint(HT+start->rchild,HT);

cout<weight<

fprintf(TreePrint,"%d\n",start->weight);

coprint(HT+start->lchild,HT);

numb--;

fclose(TreePrint);

}

}

voidTree_printing(HuffmanTreeHT,intw)

{

HuffmanTreep;

p=HT+w;

cout<<"下面打印哈夫曼树"<

coprint(p,HT);

cout<<"打印工作结束"<

}

//------------------------主函数------------------------------------

voidmain()

{

charchoice;

while(choice!

='q')

{cout<<"\n******************************"<

cout<<"欢迎使用哈夫曼编码解码系统"<

cout<<"******************************"<

cout<<"

(1)要初始化哈夫曼链表请输入'i'"<

cout<<"

(2)要编码请输入'e'"<

cout<<"(3)要译码请输入'd'"<

cout<<"(4)要打印编码请输入'p'"<

cout<<"(5)要打印哈夫曼树请输入't'"<

cout<<"(6)要打印译码请输入'y'"<

if(flag==0)cout<<"\n请先初始化哈夫曼链表,输入'i'"<

cin>>choice;

switch(choice)

{

case'i':

Initialization();

break;

case'e':

Encoding();

break;

case'd':

Decoding();

break;

case'p':

Code_printing();

break;

case't':

Tree_printing(HT,2*n-1);

break;

case'y':

Code_printing1();

break;

default:

cout<<"inputerror"<

}

}

free(z);

free(w);

free(HT);

}

费诺

#include

#include

#defineN15

intpa[N][N];

voidfano(floatp[],inta[N][N],intn,intm,intk)

{

floatg=0.0,h=0.0,d,b,c;

inti,j,flase;

if(n

{

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

{

g=p[i]+g;

}g=g/2;

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

{

h=h+p[i];

if(h>g)

{

d=h-p[i];b=h-g;c=g-d;

if(c>b)

{

for(j=n;j<=i;j++)a[j][k]=0;

fano(p,a,n,i,k+1);

for(j=i+1;j<=m;j++)a[j][k]=1;

fano(p,a,i+1,m,k+1);

}

else

{

for(j=n;j<=i-1;j++)a[j][k]=0;

fano(p,a,n,i-1,k+1);

for(j=i;j<=m;j++)a[j][k]=1;

fano(p,a,i,m,k+1);

}

break;

}

}

}

}

voidmain()

{

inti,j,k[N],n,flase=0;

floatp[N],m,H=0.0,K=0.0,sum=0.0;

cout<<"输入信源符号个数"<

cin>>n;

cout<<"输入各信源符号概率"<

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

{

cin>>p[i];

}

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

{

sum=sum+p[i];

}

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

{

if(p[i]<0.0||p[i]>1.0||sum!

=1.0)

{cout<<"inputgailverror!

";flase=1;break;}

}

if(flase==0)

{

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

for(j=0;j<=n;j++)

{pa[i][j]=10;}

fano(p,pa,1,n,1);

cout<<"信源费诺编码如下:

\n";

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

{k[i]=0;

cout<<"x"<

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

{

if(pa[i][j]!

=10)

{cout<

}

cout<<"\t码长为\t"<

}

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

{

H=-(p[i]*log(p[i])/log

(2))+H;

}

cout<<"信源熵H(X)="<

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

{

K=p[i]*k[i]+K;

}

cout<<"平均码长K="<

cout<<"编码效率为"<<(H/K)*100<<"%"<

}//if(flase==0)

cout<

}//main()

香农

#include

#include

#include

#include

classT

{

public:

T(){}

~T();

voidCreate();

voidCoutpxj();

voidCoutk();

voidCoutz();

voidPrint();

protected:

intn;

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

当前位置:首页 > 工程科技 > 交通运输

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1