returnm;
}
intpipei(char*c,intn,HuffmanCode*HC)/*在huffmancode寻找匹配的编码*/
{
inti;
for(i=1;i<5;i++)
{
if(strcmp(c,(*HC)[i])==0)
{
returni;
break;
}
}
return0;
}
d.译码
voidDecoding(HuffmanTree*HT,HuffmanCode*HC)//对文件CodeFile.txt中的代码进行解码形成原文,结果存入文件Textfile.txt中
{
inti=1,j=1,y=0,num=0,len,n=0,d,q,v,ii;
inta[2]={1,2};
charc[20];
for(i=0;i<20;i++)
c[i]='\0';
FILE*f1,*f4,*f5;
if((f1=fopen("DataFile.txt","r"))==NULL)//求权值个数n
{
printf("error\n");
}
intg[100];
charh[100];
for(i=1;;i++)
{
fscanf(f1,"%c",&h[i]);
if(h[i]=='#')
break;
fscanf(f1,"%d",&g[i]);
n++;
}
fclose(f1);
if((f4=fopen("CodeFile.txt","r"))==NULL)//读字符
{
printf("error\n");
}
printf("从数据文件CodeFile.txt中读入代码\n");
charb[100];
for(i=1;;i++)
{
fscanf(f4,"%c",&b[i]);
if(b[i]=='#')
break;
cout<
}
cout<fclose(f4);
if((f5=fopen("TextFile.txt","w"))==NULL)
{
printf("error\n");
}
cout<<"输出原文"<i=1;
j=1;
y=1;
while(true)
{
if(b[y]=='#')
break;
for(j=0;j
{
c[j]=b[y+j];
}
q=pipei(c,n,HC);
if(q!
=0)
{
printf("%c",(*HT)[q+1].ch);
fprintf(f5,"%c",(*HT)[q+1].ch);
y=y+i;
i=1;
}
else
i++;
for(ii=0;ii<20;ii++)
c[ii]='\0';
}
cout<}
四、测试与分析
1.显示主菜单,运行程序可以显示出如下界面。
2.初始化
在主菜单下选1,初始胡,即可从数据文件DataFile.txt中读入字符及每个字符的权值。
3.编码
在主菜单下选2,编码,将给定文件ToBeTran.txt中的字符输出报文。
4.译码
在主菜单下选3,完成译码功能,读取文件CodeFile.txt中的代码并输出原文。
5.退出
在主菜单下选4,退出系统
五、附录
1.哈夫曼编译码系统.h
#include
#include
#include
usingnamespacestd;
typedefstruct
{
unsignedintweight;
unsignedintparent,lchild,rchild;
charch;
}HTNode,*HuffmanTree;/*动态分配数组存储赫夫曼树*/
typedefchar**HuffmanCode;/*动态分配数组存储赫夫曼编码表*/
intmin1(HuffmanTreet,inti)
{/*函数voidselect()调用*/
intj,flag;
unsignedintk=UINT_MAX;/*取k为不小于可能的值*/
for(j=1;j<=i;j++)
if(t[j].weightk=t[j].weight,flag=j;
t[flag].parent=1;
returnflag;
}
voidselect(HuffmanTreet,inti,int*s1,int*s2)
{/*s1为最小的两个值中序号小的那个*/
intj;
*s1=min1(t,i);
*s2=min1(t,i);
if(*s1>*s2)
{
j=*s1;
*s1=*s2;
*s2=j;
}
}
voidHuffmanCoding(HuffmanTree*HT,HuffmanCode*HC,int*w,char*u,intn)/*算法6.12*/
{/*w存放n个字符的权值(均>0),构造赫夫曼树HT,并求出n个字符的赫夫曼编码HC*/
intm,i,s1,s2,start;
unsignedc,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,++u)
{
(*p).ch=*u;
(*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);/*释放工作空间*/
}
voidInitialzation(HuffmanTree*HT,HuffmanCode*HC)//初始化
{
FILE*f1;
inti,n=0;
if((f1=fopen("DataFile.txt","r"))==NULL)
{
printf("error\n");
}
intg[100];
charh[100];
printf("从数据文件DataFile.txt中读入字符及每个字符的权值\n");
for(i=1;;i++)
{
fscanf(f1,"%c",&h[i]);
if(h[i]=='#')
break;
fscanf(f1,"%d",&g[i]);
n++;
printf("%c:
",h[i]);
printf("%d\n",g[i]);
}
fclose(f1);
HuffmanCoding(HT,HC,g,h,n);
}
intEnCoding(HuffmanTree*HT,HuffmanCode*HC)//对文件ToBeTran.txt中的文本进行编码形成报文,将报文写在文件Code.txt中
{
inti,j,m=0,n=0;
FILE*f1,*f2,*f3;
if((f1=fopen("DataFile.txt","r"))==NULL)
{
printf("error\n");
}
intg[100];
charh[100];
for(i=1;;i++)
{
fscanf(f1,"%c",&h[i]);
if(h[i]=='#')
break;
fscanf(f1,"%d",&g[i]);
n++;
}
fclose(f1);
if((f2=fopen("ToBeTran.txt","r"))==NULL)
{
printf("error\n");
}
printf("从数据文件ToBeTran.txt中读入字符\n");
charu[100],a[100];
for(i=1;;i++)
{
fscanf(f2,"%c",&u[i]);
if(u[i]=='#')
break;
a[i]=u[i];
m++;
cout<}
cout<fclose(f2);
if((f3=fopen("Code.txt","w"))==NULL)
{
printf("error\n");
}
cout<<"输出报文"<for(i=0;ifor(j=1;j<=n;++j)
{
if(*(a+i)==(*HT)[j].ch)
{
printf("%s",(*HC)[j]);
fprintf(f3,"%s",(*HC)[j]);
}
}
fclose(f3);
cout<returnm;
}
intpipei(char*c,intn,HuffmanCode*HC)/*在huffmancode寻找匹配的编码*/
{
inti;
for(i=1;i<5;i++)
{
if(strcmp(c,(*HC)[i])==0)
{
returni;
break;
}
}
return0;
}
voidDecoding(HuffmanTree*HT,HuffmanCode*HC)//对文件CodeFile.txt中的代码进行解码形成原文,结果存入文件Textfile.txt中
{
inti=1,j=1,y=0,num=0,len,n=0,d,q,v,ii;
inta[2]={1,2};
charc[20];
for(i=0;i<20;i++)
c[i]='\0';
FILE*f1,*f4,*f5;
if((f1=fopen("DataFile.txt","r"))==NULL)//求权值个数n
{
printf("error\n");
}
intg[100];
charh[100];
for(i=1;;i++)
{
fscanf(f1,"%c",&h[i]);
if(h[i]=='#')
break;
fscanf(f1,"%d",&g[i]);
n++;
}
fclose(f1);
if((f4=fopen("CodeFile.txt","r"))==NULL)//读字符
{
printf("error\n");
}
printf("从数据文件CodeFile.txt中读入代码\n");
charb[100];
for(i=1;;i++)
{
fscanf(f4,"%c",&b[i]);
if(b[i]=='#')
break;
cout<
}
cout<fclose(f4