您的位置:首页 > 其它

课程设计哈夫曼编/译码系统

2017-07-03 10:29 253 查看
欢迎访问我的网站:omegaxyz.com

问题描述:利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码(解码)。对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。试为这样的信息收发站设计一个哈夫曼编译码系统。

1.基本要求

(1)初始化(Initialzation)。从数据文件DataFile.data中读入字符及每个字符的权值,建立哈夫曼树HuffTree;

(2)编码(EnCoding)。用已建好的哈夫曼树,对文件ToBeTran.data中的文本进行编码形成报文,将报文写在文件Code.txt中;

(3)译码(Decoding)。利用已建好的哈夫曼树,对文件CodeFile.data中的代码进行解码形成原文,结果存入文件Textfile.txt中;

(4)输出(Output)。输出DataFile.data中出现的字符以及各字符出现的频度(或概率);输出ToBeTran.data及其报文Code.txt;输出CodeFile.data及其原文Textfile.txt;

2.重点,难点

重点:

(1)通过实验理解哈夫曼树的特征及其应用;

(2)哈夫曼树的构造算法设计;

(3)利用构造的哈夫曼树进行编码和译码。

难点:

(1)字符的哈夫曼树编码及存储;

(2)字符的译码与串的匹配算法。

3.源代码(纯C)

#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#define MAXSIZE 50
/*©Copyright OmegaXYZ Xu Yi 2017*/
typedef struct//Huffman树的定义
{
char name;
int w;//权值
int pa;//父节点
int lch;//左子树
int rch;//右子树
}HTnode;

typedef struct//Huffman编码
{
int data;
char name1;
char *pre;
}HCnode;

int N,M;
HCnode *HC;
HTnode *HT;

void Reverse(char *str)//字符串倒置,如此便不需要反向编码
{
int i,j;
char ch;
for(i=0,j=strlen(str)-1;i<j;i++,j--){
ch=str[i];
str[i]=str[j];
str[j]=ch;
}
}

int min_node(HTnode *HT,int n)//寻找Node中最小的节点
{
int i,min;
for(i=1;HT[i].pa;i++);//寻找根节点
min=i;
for(i=1;i<n;i++)
if(!HT[i].pa)
if(HT[i].w<HT[min].w)
min=i;
HT[min].pa=1;
return min;
}

void Output_HT(HTnode *HT)//输出Huffman树
{
int i;
printf(" 编号  名称 权值 父节点 左子树 右子树\n");
for(i=1;i<2*N;i++){
printf(" |%-5d %c    %-5d %-5d %-6d %-4d|\n",i,
HT[i].name,HT[i].w,
HT[i].pa,HT[i].lch,
HT[i].rch);
}
}

/*©Copyright OmegaXYZ Xu Yi 2017*/

void PrintHC(HCnode *HC)//输出Huffman编码
{
FILE *f1,*f2;
int i=0,j=0,x=0,n=0,wpl=0;//wpl带权路径长度
char temp[50];
if((f1=fopen("ToBeTran.txt","r"))==NULL){//打开ToBeTran.txt
printf("open failed!\n");exit(0);
}
if
11283
((f2=fopen("Code.txt","w"))==NULL){//打开Code.txt
printf("open failed!\n");exit(0);
}
printf("输出Huffman编码\n");
for(i=1;i<=N;i++)
{
printf("%c-->%s",HC[i].name1,HC[i].pre);
x=strlen(HC[i].pre);
wpl+=(HC[i].data*x);
printf("\n");
}
i=0;
while(!feof(f1)){//从ToBeTran中读取字符并写入Code
temp[i]=fgetc(f1);
for(j=1;j<=N;j++)
if(temp[i]==HC[j].name1)
{
fprintf(f2,"%s",HC[j].pre);
}
i++;
}
fprintf(f2,"\b");
printf("\n带权路径长度(WPL) is %d\n",wpl);
fclose(f1);
fclose(f2);
}

/*©Copyright OmegaXYZ Xu Yi 2017*/

HTnode *Create()//构造Huffman树
{
FILE *fp;
int i,Si,Sj;//找出来的两个最小子树保存在Si和Sj里面
HTnode *HT;
HT=(HTnode *)malloc((2*N)*sizeof(HTnode));//给HT分配2N-1这里分配2N个
printf("读取%d个叶节点的权值并生成Hufman Tree表格形式:\n",N);
if((fp=fopen("DataFile.txt","rt"))==NULL){//读取DataFile的文件
//A,10a,2b,3c,10d,11e,20f,11g,10h,20i,14j,3k,7l,15m,9n,3o,25p,6q,2r,5s,20t,21u,9v,1w,5x,6y,8z,3 ,28!,8
printf("can not find file DataFile failed!\n");exit(0);
}
for(i=1;i<=N;i++)
{
fscanf(fp,"%c,%d",&HT[i].name,&HT[i].w);//将Data的名称和权值赋值给HT
HT[i].lch=HT[i].rch=HT[i].pa=0;//初始化
}
printf("\n");
for(;i<=M;i++)
HT[i].lch=HT[i].rch=HT[i].pa=HT[i].w=0;//对其它多余的树进行初始化
for(i=N+1;i<=M;i++)
{
Si=min_node(HT,i);//寻找最小的节点
Sj=min_node(HT,i);//同上
HT[i].w=HT[Si].w+HT[Sj].w;//创建
HT[Si].pa=HT[Sj].pa=i;
HT[i].lch=Si;HT[i].rch=Sj;
}
return HT;
}

/*©Copyright OmegaXYZ Xu Yi 2017*/

void Decoding(HTnode *HT)//解码
{
FILE *fp1,*fp2;
char ch[50];
char cod[200];
int f,root,i=0,j=0;
if((fp1=fopen("CodeFile.txt","r"))==NULL){
printf("open file failed");exit(0);
}
if((fp2=fopen("Textfile.txt","w"))==NULL){
printf("open file failed");exit(0);
}
while(!feof(fp1)){//将Codefile的文件给cod[]
fscanf(fp1,"%c",&cod[i]);
i++;
}
i=1;
while(HT[i].pa){i++;}//寻找根节点
root=i;
i=0;
while(cod[i]!='\b')//结尾
{
f=root;
while(HT[f].lch!=NULL)//不为空
{
if(cod[i]=='0') f=HT[f].lch;
else f=HT[f].rch;
i++;
}
ch[j++]=HT[f].name;
}
ch[j]='\0';
printf("\nCodeFile.txt解码为:%s\n",ch);i=0;
fprintf(fp2,"%s\b",ch);
fclose(fp1);
fclose(fp2);
}

void Output()   //输出Textfile.txt、ToBeTran.txt、Code.txt、CodeFile.txt、Textfile.txt
{
int c;
char b;
FILE *fp1,*fp2,*fp3,*fp4,*fp5;
if((fp1=fopen("Datafile.txt","r"))==NULL){
printf("open file0 failed!\n");exit(0);
}
if((fp1=fopen("Datafile.txt","r"))==NULL){
printf("open file0 failed!\n");exit(0);
}
if((fp2=fopen("ToBeTran.txt","r"))==NULL){
printf("open file ToBeTran failed!\n");exit(0);
}
if((fp3=fopen("Code.txt","r"))==NULL){
printf("open file Code failed!\n");exit(0);
}
if((fp4=fopen("CodeFile.txt","r"))==NULL){
printf("open file CodeFile failed!\n");exit(0);
}
if((fp5=fopen("Textfile.txt","r"))==NULL){
printf("open file Textfile failed!\n");exit(0);
}
printf("\n输出DataFlie中的字符及其权值:\n");
while(!feof(fp1)){
fscanf(fp1,"%c,%d", &b,&c);
printf("'%c'---%d\n",b,c);
}
printf("\n\n输出ToBeTran:\n");
while(!feof(fp2)){
fscanf(fp2,"%c",&b);
printf("%c",b);
}
printf("\n\n输出Code.txt:\n");
while(!feof(fp3)){
fscanf(fp3,"%c",&b);
printf("%c",b);
}
printf("\n\n输出CodeFile.txt:\n");
while(!feof(fp4)){
fscanf(fp4,"%c",&b);
printf("%c",b);
}
printf("\n\n输出Textfile.txt:\n");
while(!feof(fp5)){
fscanf(fp5,"%c",&b);
printf("%c",b);
}
printf("\n");
fclose(fp1);fclose(fp2);fclose(fp3);fclose(fp4);fclose(fp5);
}

void Output2(int n)   //输出Textfile.txt、ToBeTran.txt、Code.txt、CodeFile.txt、Textfile.txt
{
int c;
char b;
FILE *fp1,*fp2,*fp3,*fp4,*fp5;
switch(n)
{
case 1:printf("\n输出DataFlie中的字符及其权值:\n");
if((fp1=fopen("Datafile.txt","r"))==NULL){
printf("open file0 failed!\n");exit(0);}
while(!feof(fp1)){fscanf(fp1,"%c,%d", &b,&c);
printf("'%c'---%d\n",b,c);}fclose(fp1);break;
case 2:printf("\n\n输出ToBeTran:\n");
if((fp2=fopen("ToBeTran.txt","r"))==NULL){
printf("open file ToBeTran failed!\n");exit(0);}
while(!feof(fp2)){fscanf(fp2,"%c",&b);
printf("%c",b);}fclose(fp2);break;
case 3:printf("\n\n输出Code.txt:\n");
if((fp3=fopen("Code.txt","r"))==NULL){
printf("open file Code failed!\n");exit(0);}
while(!feof(fp3)){fscanf(fp3,"%c",&b);
printf("%c",b);}fclose(fp3);break;
case 4:printf("\n\n输出CodeFile.txt:\n");
if((fp4=fopen("CodeFile.txt","r"))==NULL){
printf("open file CodeFile failed!\n");exit(0);}
while(!feof(fp4)){fscanf(fp4,"%c",&b);
printf("%c",b);}fclose(fp4);break;
case 5:printf("\n\n输出Textfile.txt:\n");
if((fp5=fopen("Textfile.txt","r"))==NULL){
printf("open file Textfile failed!\n");exit(0);}
while(!feof(fp5)){fscanf(fp5,"%c",&b);
printf("%c",b);}fclose(fp5);break;
default:printf("ERROR!");
}
printf("\n");
}

/*©Copyright OmegaXYZ Xu Yi 2017*/

int main()
{
int i;
FILE *fp;
char **code;//构建一个二维数组解码用
char ope;
msgbox();//信息栏自己定义哦
printf("根据Data文件请输入叶节点个数(此文件输入>28):");
while(scanf("%d",&N))
{
if(N>0&&N<=500){
M=2*N-1;
code=(char**)malloc(100*sizeof(char));
for(i=0;i<N;i++)
code[i]=(char *)malloc(8*sizeof(char));
Output2(1);
printf("读取DataFile中的字符及权值,建立Huffman树:\n");
HT=Create();
Output_HT(HT);
printf("\n");
printf("对Huffman树进行编码:\n");
HC=Coding(HT);
PrintHC(HC);
printf("-------------------------------------------------------------------\n");
printf("将ToBeTran的内容改写成编码写入Code.txt\n");
Output2(2);
Output2(3);
printf("-------------------------------------------------------------------\n");
printf("对文件CodeFile.data中的代码进行解码形成原文,结果存入文件Textfile.txt中\n");
Decoding(HT);
Output2(4);
Output2(5);
printf("-----------------------------总输出函数--------------------------------\n");
Output();
break;
}
else printf("请重新输入:\n");
}
return 0;
}




内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐