浅谈如何利用C 实现赫夫曼编码/译码器
创始人
2024-04-16 12:11:38
0

现在我就来说明一下这个赫夫曼编码/译码器实现方法吧。整个项目我就用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(work2);  
  80.         fclose(txtfile);  
  81.         fclose(codef);   
  82.  
  83. }  

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

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

【编辑推荐】

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

相关内容

热门资讯

如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
施耐德电气数据中心整体解决方案... 近日,全球能效管理专家施耐德电气正式启动大型体验活动“能效中国行——2012卡车巡展”,作为该活动的...
Windows恶意软件20年“... 在Windows的早期年代,病毒游走于系统之间,偶尔删除文件(但被删除的文件几乎都是可恢复的),并弹...
20个非常棒的扁平设计免费资源 Apple设备的平面图标PSD免费平板UI 平板UI套件24平图标Freen平板UI套件PSD径向平...
德国电信门户网站可实时显示全球... 德国电信周三推出一个门户网站,直观地实时提供其安装在全球各地的传感器网络检测到的网络攻击状况。该网站...
着眼MAC地址,解救无法享受D... 在安装了DHCP服务器的局域网环境中,每一台工作站在上网之前,都要先从DHCP服务器那里享受到地址动...
为啥国人偏爱 Mybatis,... 关于 SQL 和 ORM 的争论,永远都不会终止,我也一直在思考这个问题。昨天又跟群里的小伙伴进行...