数据结构实训——哈夫曼编码/译码器

本文介绍了一个基于哈夫曼编码的编译码系统设计,包括统计字符频率、构建哈夫曼树、编码、译码等功能。系统能够处理包含27个字符的文本,提高通信效率。测试数据涉及字符串 'THIS PROGRAM IS MY FAVORITE' 的编码和译码过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

哈夫曼(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++)
    
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值