哈夫曼(Huffman)编/译码器(限1人完成)
【问题描述】
利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码(复原)。对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。试为这样的信息收发站写一个哈夫曼码的编/译码系统。首先输入一段包含27个字符(包含空格)的文字(可以存在一个文件中),然后统计出各个字符出现的次数,以每个字符出现的次数为权值构造哈夫曼树,求得哈夫曼编码。
【基本要求】
一个完整的系统应具有以下功能:
1、 O: 输入一段字符(要包含27各字符)存入文件chartexfile中,统计出各个字符出现的次数并以表格的形式存入文件charsumfile中.
例如如下表:
字符 空格 A B C D E F G H I J K L M
频度 186 64 13 22 32 103 21 15 47 57 1 5 32 20
字符 N O P Q R S T U V W X Y Z
频度 57 63 15 1 48 51 80 23 8 18 1 16 1
2、I:初始化(Initialization)。从终端读入字符集大小n,n个字符及n个权值,建立哈夫曼树,并将它存于文件hfmTree中。
3、 E:编码(Encoding)。利用以建好的哈夫曼树(如不在内存,则从文件hfmTree中读入),
对文件ToBeTran中的正文进行编码,然后将结果存入文件CodeFile中。
4、D:译码(Decoding)。利用已建好的哈夫曼树将文件CodeFile中的代码进行译码,结果存入文件TextFile中。
5. P:打印代码文件(Print)。将文件CodeFile以紧凑格式显示在终端上,每行50个代码。
同时将此字符形式的编码文件写入文件CodePrin中。
4、 T:打印哈夫曼树(Tree Printing)。将已在内存中的哈夫曼树以直观的方式(树或凹入
表形式)显示在终端上,同时将此字符形式的哈夫曼树写入文件TreePrint中。
【测试数据】
用文件charsumfile给出的字符集和频度的实际统计数据建立哈夫曼树,并实现以下报文的编码和译码:“THIS PROGRAM IS MY FAVORITE”。
测试数据要求:
要求使用1、全部合法数据;2、整体非法数据;3、局部非法数据。进行程序测试,以保证程序的稳定
#include<stdio.h>
#include<string.h>
#define maxval 10000.0
#define maxsize 10000 //哈夫曼编码的最大位数
typedef struct
{
char ch;
float weight=-1;
int lchild,rchild,parent;
} hufmtree;
typedef struct
{
char bits[10000]; //位串
int start; //编码在位串中的起始位置
char ch; //字符
} codetype;
int n,m;
hufmtree tree[20000];
codetype code[10000];
void TongJi(); //统计字符个数
void huffman(hufmtree tree[]);//建立哈夫曼树
void huffmancode(codetype code[],hufmtree tree[]);//根据哈夫曼树求出哈夫曼编码
void decode(hufmtree tree[]);//依次读入电文,根据哈夫曼树译码
void print(); //打印代码文件,输出 CodeFile.txt
void TreePrinting();//打印哈夫曼树
int main()
{
while(1)
{
int t;
printf("---------------菜单-------------------\n");
printf("1.输入一段字符,统计出各个字符出现的次数.\n");
printf("2.建立哈夫曼树.\n");
printf("3.编码.\n");
printf("4.译码.\n");
printf("5.打印编码\n");
printf("6.打印哈夫曼树\n");
printf("7.退出\n");
printf("---------------------------------------\n");
printf("请选择你要进行的操作:");
scanf("%d",&t);
switch(t)
{
case 1:
TongJi();
break;
case 2:
huffman(tree);//建立哈夫曼树
printf("哈夫曼树已建立!\n");
break;
case 3:
huffmancode(code,tree);//根据哈夫曼树求出哈夫曼编码
break;
case 4:
decode(tree);//依次读入电文,根据哈夫曼树译码*/
break;
case 5:
print();
break;
case 6:
TreePrinting();
break;
case 7:
return 0;
}
}
return 0;
}
void TongJi() //统计字符个数
{
FILE *out1,*out2;
out1=fopen("chartexfile.txt","w");
out2=fopen("charsumfile.txt","w");
if(out1==NULL||out2==NULL)
{
printf("打开文件失败\n");
}
char s[1000];
int i=0;
char zf[1000]= {
0}, z[1000];
int cnt=1,k,num[1000]= {
0};
printf("请输入字符串(空格以-代替,按回车结束):");
scanf("%s",s);
k=strlen(s);
fprintf(out1,"%s",s);
for(i=0; i<k; i++)