成长路上的小程序之—— 哈夫曼编码、译码

这篇博客记录了作者在大二数据结构课程中完成的哈夫曼编码和译码上机任务,作为课程设计的一部分。作者分享了这次经历的重要性,认为相比之前较为简单的《学生通讯录》课程设计,这次的程序包含了更巧妙的思路,并自豪地表示是独立完成的。

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

这是大二数据结构第七次上机老师布置的任务:实现文件操作,对文件进行哈夫曼编码、译码

之所以为此写一篇博客,是因为自认为这个程序对我的意义比较重大。

我是以一个课程设计的要求来写的,大一结束的暑假也做了一个课程设计:《学生通讯录》

但是太水了,完全没有难度。

这个相对来说则有一些巧妙的思想,完全是我独立完成的!

哈哈哈

代码如下:

#include <cstdlib>
#include <iostream>
#include <string.h>
#include <ctype.h>
#include <conio.h>
#include "huffmantree.h"
#define MAX 1000000
using namespace std;

char str[MAX],ch[20];
int  n=0;
FILE *fp1, *fp2;
HuffmanTree HT;
HuffmanCode HC;

int main(int argc, char *argv[])
{
    void menu(void);
    menu();
    system("PAUSE");
    return EXIT_SUCCESS;
}

void menu(void)//菜单 
{
    void encoded(void);//编码 
    void decoded(void);//译码 
    system("cls");
    printf("\n\t\t**************编码译码菜单********\n\n");
    printf("\n\t\t**************1、编码\n");
    printf("\n\t\t**************2、译码\n");
    printf("\n\t\t**************3、退出\n");
    printf("\n\t\t**********************************\n\n");
    printf("\n\n\t\t************请选择(1/2/3):\n\n");
    char ch=getch();//不需要回车 
    switch(ch)
    { 
     case '1': encoded();break;
     case '2': decoded();break;
     case '3': exit(0);
    }
    
}

void encoded()
{
    int w[30];
    printf("\n\t\t******************编码过程如下:\n"); 
    //编码 
    fp1 = fopen("in.txt", "r");
    fp2 = fopen("out.txt", "w");
    fgets(&str[1],MAX,fp1);
    //文件读取完成 ,从1下标处开始读取,因为哈夫曼编码从1开始 
    //这里&str[1]个人觉得比较巧妙  ^_^ 
    int len = strlen(&str[1]);//字符总个数 
    printf("\n\t\t******************字符总个数为 %d 个\n",len); 
    int count[30] = {0};
    for(int i=1; i<=len; i++)
     if(isalpha(str[i]))
     {
      str[i] = tolower(str[i]);//全部转换为小写字母 
      count[str[i]-'a'+1]++;//统计字符出现个数,简单明了,值得表扬 ^_^ 
     }
    for (int i=1; i<=26; i++)
     if (count[i])
     {
      w[i] = count[i];//赋给哈夫曼中的权值 
      n++;//统计出现字母类别个数 
     }
    HuffmanCoding(HT,HC,w,n);//调用哈夫曼 
    
    for(int i=1; i<len; i++)
    {
     if(isalpha(str[i]))
      fputs(HC[str[i]-'a'+1],fp2);
     else
      fprintf(fp2,"%c",str[i]);
    }   
    fclose(fp1);
    fclose(fp2);
    printf("\n\n\t\t编码成功!\n");
    printf("\n\n\t\t编码结果保存在out.txt文件中");
    printf("请查看文件! ");
    system("pause"); 
    menu();
}
    
void decoded()
{
    void ncpy(char ch[],char* str,int index,FILE* fp,int* countc);
    printf("\n\t\t******************译码过程如下:\n");
    fp1=fopen("out.txt","r");
    fp2=fopen("result.txt","w");
    fgets(str,MAX,fp1);//取出编码结果 
    int index=2;
    int len=strlen(str);
    int countc=1;
    for(int j=0; j<len; )
    {
     //这里我觉得是我代码中最值得称赞的地方
     //从这里可以看到刷题的影子 
     ncpy(ch,&str[j],++index,fp2,&countc);
     for(int i=1; i<=n; i++)
      if(!strcmp(ch,HC[i]))
      {      
       fprintf(fp2,"%c",'a'+i-1);
       j+=index;
       index=2;
       //判别一个字符成功,继续判别下一个字符 
       //改变j的值,使从下一段01代码中复制
       //重新赋值index=2; 
       countc=1;
      }
    }
    fclose(fp1);
    fclose(fp2); 
    printf("\n\t\t译码成功!\n");
    printf("\n\t\t译码结果保存在result.txt文件中!\n");
    printf("\n\t\t请查看! ");
    system("pause");
    menu(); 
} 

void ncpy(char ch[],char* str,int index,FILE* fp,int* countc)
//自己写的复制字符串函数,舍掉了字符串中的符号 
{
    int k=0;
    for(int i=0; i<index; i++)
     if(str[i]=='1'||str[i]=='0')
      ch[k++]=str[i];
     else if(*countc)
     {
      fprintf(fp,"%c",str[i]);
      *countc=0;
      //这里是我完成程序前的最后一关
      //用countc控制即使多次调用函数,也只输出一次符号 
     }
    ch[k]='\0';
}


继续加油~!~!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值