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

来源:互联网 发布:永恒之塔捏脸数据5.3 编辑:程序博客网 时间:2024/05/21 10:38

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

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

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

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

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

哈哈哈

代码如下:

#include <cstdlib>#include <iostream>#include <string.h>#include <ctype.h>#include <conio.h>#include "huffmantree.h"#define MAX 1000000using 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';}


继续加油~!~!