浅谈如何利用C++实现赫夫曼编码/译码器

开发 后端
前些日子,笔者的一个朋友给了他一个有点烦的任务。做个赫夫曼编码、译码器给她,这里就把笔者实现赫夫曼编码/译码器的过程写下来,供大家参考。

现在我就来说明一下这个赫夫曼编码/译码器实现方法吧。整个项目我就用win32控制台程序写的。这样可以方便测试,排除其他麻烦。

首先,我们来看看main函数:

  1. void main()  
  2. {  
  3.         char choice=' ';  
  4.         while(choice!='q')  
  5.         {       cout<<"\n******************************"<                cout<<" 欢迎使用赫夫曼编码译码系统"<                cout<<"******************************"<                cout<<"(1)要初始化赫夫曼链表请输入'i'"<                cout<<"(2)输入要编码的字符'w'"<                cout<<"(3)要编码请输入'e'"<                cout<<"(4)要译码请输入'd'"<                cout<<"(5)要打印编码请输入'p'"<                cout<<"(6)要打印赫夫曼树请输入't'"<                cout<<"(7)要离开请输入'q'"<                if(flag==0)cout<<"\n请先初始化赫夫曼链表,输入'i'"<                cin>>choice;  
  6.                  switch(choice)  
  7.                  {  
  8.                  case 'i':  
  9.                                 Initialization();  
  10.                                 break;  
  11.                  case 'w':  
  12.                                 InputCode();  
  13.                                 break;  
  14.                  case 'e':  
  15.                                 Encoding();  
  16.                                 break;  
  17.                  case 'd':  
  18.                                 Decoding();  
  19.                                 break;  
  20.                  case 'p':  
  21.                                 Code_printing();  
  22.                                 break;  
  23.                  case 't':  
  24.                                     Tree_printing(HT,2*n-1);  
  25.                                     break;  
  26.                  case 'q':  
  27.                                 break;  
  28.                  default:  
  29.                                 cout<<"input error"<                 }   
  30.  
  31.         }  
  32.        free(z);  
  33.        free(w);  
  34.        free(HT);  

这个函数主要就是和用户交互使用。这个过程我用switch case 来实现,你们也可以选择其他的方式实现如if else ,这个就个人爱好选择。下面我们来看看初始化赫夫曼树的函数Initialization()。

  1. void Initialization()  
  2. {  
  3.         flag=1;  
  4.         int num;  
  5.         int num2;  
  6.         cout<<"下面初始化赫夫曼链表"<        cin>>num;  
  7.         n=num;  
  8.         w=(int*)malloc(n*sizeof(int));  
  9.         z=(char*)malloc(n*sizeof(char));  
  10.         cout<<"\n请依次输入"<        char base[2];  
  11.         for(i=0;i   {  
  12.         cout<<"第"<        gets(base);//这个地方有点小小的问题  
  13.         *(z+i)=*base;  
  14.         }  
  15.         for(i=0;i<=n-1;i++)  
  16.         {  
  17.                 cout<        }  
  18.         cout<<"\n请依次输入"<        for(i=0;i<=n-1;i++)  
  19.         {  
  20.          cout<         cin>>num2;  
  21.          *(w+i)=num2;  
  22.    }  
  23.         HuffmanCoding(HT,HC,w,n);  
  24. //------------------------打印编码-------------------------------------------  
  25.         cout<<"字符对应的编码为:"<        for(i=1;i<=n;i++)  
  26.         {  
  27.                 //cout<<"字符"<<*(z+i-1)<<"的编码";  
  28.                 puts(HC[i]);  
  29.         }  
  30. //--------------------------将赫夫曼编码写入文件------------------------  
  31.         cout<<"下面将赫夫曼编码写入文件"<   
  32.  
  33.         FILE *hfmTree;  
  34.         char r[]={' ','\0'};         
  35.         if((hfmTree=fopen("hfmTree.txt","w"))==NULL)  
  36.    {  
  37.    cout<<"can not open file"<   return;  
  38.    }   
  39.  
  40.         fputs(z,hfmTree);  
  41.         for(i=0;i        {  
  42.          fprintf(hfmTree,"%6d",*(w+i));  
  43.          fputs(r,hfmTree);  
  44.    }  
  45.         for(i=1;i<=n;i++)  
  46.         {  
  47.          fputs(HC[i],hfmTree);  
  48.          fputs(r,hfmTree);  
  49.         }  
  50.         fclose(hfmTree);  
  51.         cout<<"已将字符与对应编码写入根目录下文件hfmTree.txt中"<} 

上述代码中有个小问题,已经用红色标示,这个地方获取数据的时候有一次是没有输入就直接执行的。这个疑问我一直都没想通。初始化的结果放入hfmTree.txt的文件中。

下面来看看输入要编码的字符的函数InputCode()

  1. void InputCode()  
  2. {  
  3.     //cout<<"请输入你想要编码的字符"<    FILE *tobetran;  
  4.     char str[100];  
  5.     if((tobetran=fopen("tobetran.txt","w"))==NULL)  
  6.     {  
  7.         cout<<"不能打开文件"<        return;  
  8.     }  
  9.     cout<<"请输入你想要编码的字符"<    cin>>str;  
  10.     fputs(str,tobetran);  
  11.     cout<<"获取报文成功"<    fclose(tobetran);  
  12. }  

这个函数里我也碰到了一个问题,cin>>str;部分一开始的时候,我是用gets代替的,不过问题就是用gets我不用输入就能直接执行完函数。这个郁闷啊。

下面来看看赫夫曼编码/译码器函数

  1. //---------------------编码函数---------------------------------  
  2. void Encoding()  
  3. {  
  4.         cout<<"下面对目录下文件tobetran.txt中的字符进行编码"<   
  5.  
  6.         FILE *tobetran,*codefile;   
  7.  
  8.         if((tobetran=fopen("tobetran.txt","rb"))==NULL)  
  9.         {  
  10.                 cout<<"不能打开文件"<        }  
  11.         if((codefile=fopen("codefile.txt","wb"))==NULL)  
  12.         {  
  13.                 cout<<"不能打开文件"<        }   
  14.  
  15.         char *tran;  
  16.         i=99;  
  17.         tran=(char*)malloc(100*sizeof(char));   
  18.  
  19.         while(i==99)  
  20.         {  
  21.                 if(fgets(tran,100,tobetran)==NULL)  
  22.                 {  
  23.                         cout<<"不能打开文件"<                        break;  
  24.                 }  
  25.                 for(i=0;*(tran+i)!='\0';i++)  
  26.                 {  
  27.                         for(j=0;j<=n;j++)  
  28.                         {  
  29.                                 if(*(z+j-1)==*(tran+i))  
  30.                                 {  
  31.                                   fputs(HC[j],codefile);  
  32.                                   if(j>n)  
  33.                                   {  
  34.                                    cout<<"字符错误,无法编码!"<                                   break;  
  35.                                   }  
  36.                                 }  
  37.                         }  
  38.                 }  
  39.         }  
  40.         cout<<"编码工作完成"<        fclose(tobetran);  
  41.         fclose(codefile);  
  42.         free(tran);  
  43. }   
  44.  
  45. //-----------------译码函数---------------------------------  
  46. void Decoding()  
  47. {  
  48. cout<<"下面对根目录下文件codefile.txt中的字符进行译码"<        FILE *codef,*txtfile;  
  49.         if((txtfile=fopen("\\Textfile.txt","w"))==NULL)  
  50.         {  
  51.                 cout<<"不能打开文件"<        }  
  52. //txtfile=fopen("Textfile.txt","w");  
  53.         if ((codef=fopen("codefile.txt","r"))==NULL)  
  54.         {  
  55.                 cout<<"不能打开文件"<        }  
  56. //codef=fopen("codefile.txt","r");  
  57.    char *work,*work2,i2;  
  58. int i4=0,i,i3;  
  59.         unsigned long length=10000;  
  60.         work=(char*)malloc(length*sizeof(char));  
  61. fgets(work,length,codef);  
  62. work2=(char*)malloc(length*sizeof(char));  
  63. i3=2*n-1;  
  64. for(i=0;*(work+i)!='\0';i++)  
  65. {  
  66.    i2=*(work+i);  
  67.    if(HT[i3].lchild==0)   
  68.    {  
  69.     *(work2+i4)=*(z+i3-1);  
  70.     i4++;  
  71.     i3=2*n-1;  
  72.     i--;  
  73.    }  
  74.    else if(i2=='0') i3=HT[i3].lchild;  
  75.    else if(i2=='1') i3=HT[i3].rchild;  
  76. }  
  77. *(work2+i4)='\0';  
  78. fputs(work2,txtfile);  
  79. cout<<"译码完成"<free(work);  
  80. free(work2);  
  81.         fclose(txtfile);  
  82.         fclose(codef);   
  83.  
  84. }  

整个赫夫曼编码/译码器实现过程也就这样了。

我没有学过数据结构,我只是看过一些资料,这里可能会有不好的地方,高手可以指点一下。

【编辑推荐】

  1. C++之运算符重载,输入输出流详细介绍
  2. C++、Java与C#的命名规范总结
  3. C++类成员函数的重载、覆盖与隐藏
  4. Eclipse下C/C++环境搭建
  5. Java与C++语言在作用域上的差异浅析
责任编辑:彭凡 来源: cnblogs
相关推荐

2010-01-25 13:43:09

C++算术编码

2015-03-24 13:46:29

C++多线程计数器特性实现

2010-03-05 16:56:42

Python绑定C++

2009-07-16 10:58:11

C#枚举

2011-08-04 09:35:09

Objective-C 编码规范

2010-01-27 16:39:48

C++编译器

2009-06-16 10:20:05

多继承C#

2009-08-28 16:08:28

C#利用资源文件

2009-05-12 10:36:38

OracleREDO恢复

2024-01-16 11:43:38

C++HashMap

2017-10-30 17:15:35

大数据C++TensorFlow

2022-04-01 13:10:20

C++服务器代码

2021-03-26 08:40:28

Java数据结构算法

2018-05-21 08:22:14

自编码器协同过滤深度学习

2009-06-24 10:49:16

JavaScript

2012-09-18 13:26:39

CC++

2010-01-13 18:44:03

C++编译

2009-09-04 17:34:11

C#CC++

2024-01-31 08:33:06

C++编程计算器

2011-04-08 09:52:44

C++C#DLL
点赞
收藏

51CTO技术栈公众号