程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 淺談如何利用C++實現赫夫曼編碼/譯碼器

淺談如何利用C++實現赫夫曼編碼/譯碼器

編輯: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++語言在作用域上的差異淺析

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved