日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数据结构实验三:Huffman树及Huffman编码的算法实现

發布時間:2024/4/11 编程问答 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构实验三:Huffman树及Huffman编码的算法实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Exp03 Huffman樹及Huffman編碼的算法實現

Author: Maskros

實驗目的

  • 了解該樹的應用實例,熟悉掌握Huffman樹的構造方法及Huffman編碼的應用,

  • 了解Huffman樹在通信、編碼領域的應用過程。Huffman樹及Huffman編碼的算法實現

實驗內容與要求

  • 輸入一段100—200字的英文短文,存入一文件a中。

  • 寫函數統計短文出現的字母個數n及每個字母的出現次數

  • 寫函數以字母出現次數作權值,建Haffman樹(n個葉子),給出每個字母的Haffman編碼。

  • 用每個字母編碼對原短文進行編碼,碼文存入文件b中。

  • 用Haffman樹對b中碼文進行譯碼,結果存入文件c中,比較a,c是否一致,以檢驗編碼、譯碼的正確性。

  • 實驗內容和實驗步驟

    通過優先隊列 priority_queue和 map簡化建樹和編碼過程

    • 大體思路:
      • 需要進行文件讀寫操作,通過fopen(), fputc(), fputs(), fclose()等函數實現
      • 定義結點 struct Node, 其中存儲char alpha 作為字母,int value對應字母的權值,Node *lchild,*rchild對應左右孩子結點,string code存儲編碼后的Huffman編碼,構造函數不再贅述。
      • write_file(char *name)函數,為了讀入回車字符,使用* 作為讀入結束標志,同時存入數組和文件中
      • cal_alpha(vector<char> v,int l) 函數運用map<char,int>進行映射,鍵為字母,值為出現的次數,使用print_times()函數進行打印
      • create_HT()函數用于建立Huffman樹,首先將map<char,int> 壓入優先隊列priority_queue<Node*,vector<Node*>,cmp> 中,其中bool cmp(Node *a,Node *b) 定義按照字母的權重從小到大排序,這樣每次取出隊首兩個結點構成新節點壓入隊列,循環往復直到隊空,將最后兩個結點結合作為Huffman樹的根節點
      • encode_HT(Node *p, string ss) 函數用于編碼Huffman樹,從根節點前序遍歷整棵樹,左子樹在字符串后加0, 右子樹加1 , 遞歸遍歷即可, print_hfcode()用于打印哈夫曼編碼
      • decode_Text(char *name)函數用于對文件中的密文解碼,從根結點遍歷整棵樹,檢測到0 就往左孩子找,1 就去右孩子找,如果對應結點的alpha值為字母即將其添加到譯文中,然后在返回根節點遍歷,以此往復,最后將結果譯文寫入文件中
      • tips:程序對只有一個結點的Huffman樹進行了特判
    • 輸入形式:一段英文短文可包含逗號等標點以及回車,空格等白字符。輸入以 * 符號結束
    • 輸出形式:包含字母數量、各字母的出現次數、每個字母對應的哈夫曼編碼。原文、編碼后的密文、以及解碼后的密文分別保存在源目錄的a.txt, b.txt, c.txt中
    //presented by Maskros - 2021/05/20 #include<bits/stdc++.h> using namespace std; vector<char> s; //Save the original text string s2=""; //Save the original text after encoding map<char,int> mp; //Count the number of occurrences of letters map<char,string> hfcode; //Save Huffman Code int len,len2; //Text length map<char,int>::iterator it; map<char,string>::iterator it2; struct Node{int value;char alpha;Node *lchild,*rchild;string code;Node(){}Node(int v,char a,Node *l,Node *r):value(v),alpha(a),lchild(l),rchild(r){code="";} }; Node *HTroot; void write_file(char *name){ //Write filecout<<"Print \'*\' to stop typing...."<<endl<<endl;char ch;if(FILE *fp=fopen(name,"w")){while(1){ch=getchar();if(ch=='*') break; //while read '*' then end inputfputc(ch,fp);s.push_back(ch);}fclose(fp);} } void cal_alpha(vector<char> v,int l){ //Count the number of words appearing in a letterfor(int i=0;i<l;i++){if((v[i]<='Z'&&v[i]>='A')||(v[i]<='z'&&v[i]>='a'))mp[v[i]]++;} } void print_times(){ //Print the number of occurrences and the number of each letterit=mp.begin();putchar('\n');cout<<"n="<<mp.size()<<endl;while(it!=mp.end()){cout<<it->first<<": "<<it->second<<endl; it++;}putchar('\n'); } struct cmp{ //Used for priority queue sortingbool operator()(Node *a,Node *b){return a->value>b->value;} }; void create_HT(){ //Build Huffman Treepriority_queue<Node*,vector<Node*>,cmp> q;for(it=mp.begin();it!=mp.end();it++){q.push(new Node(it->second,it->first,NULL,NULL));}if(mp.size()==1){HTroot=q.top(); return;} //Huffman tree has only one root nodeNode *left,*right;while(1){left=q.top(); q.pop();right=q.top(); q.pop();if(q.empty()){HTroot=new Node(left->value+right->value,'0',left,right);break;} q.push(new Node(left->value+right->value,'0',left,right));} } void encode_HT(Node *p,string ss){ //Coding the Huffman treeif(!p) return;p->code=ss;if(p->alpha!='0'){if(p->code.length()==0){ hfcode[p->alpha]="1"; return;} //If the Huffman tree has only one root node, the default is 1hfcode[p->alpha]=p->code; }encode_HT(p->lchild,ss+"0");encode_HT(p->rchild,ss+"1"); } void print_hfcode(){ //Print Huffman codefor(it2=hfcode.begin();it2!=hfcode.end();it2++){cout<<it2->first<<" => "<<it2->second<<endl;} } void encode_Text(char *name){ //Write the encoded original text to the filechar tmp[100];string st;if(FILE *fp=fopen(name,"w")){for(int i=0;i<len;i++){ st=hfcode[s[i]];s2+=st;strcpy(tmp,st.c_str()); //String to char arrayfputs(tmp,fp);}fclose(fp);} } void decode_Text(char *name){ //Decode b.txt and save in c.txtNode *tmp=HTroot;char decode[10000];int j=0;if(mp.size()==1){ //If the Huffman tree has only one root nodefor(int i=0;i<s2.length();i++){if(tmp->alpha!='0') decode[j++]=tmp->alpha; }}else{for(int i=0;i<=s2.length();i++){if(tmp->alpha!='0'){decode[j++]=tmp->alpha;tmp=HTroot;}if(s2[i]=='0') tmp=tmp->lchild;else tmp=tmp->rchild;}}if(FILE *fp=fopen(name,"w")){ for(int i=0;i<j;i++) fputc(decode[i],fp);fclose(fp);} } int main(){char a[]="a.txt";char b[]="b.txt";char c[]="c.txt";write_file(a);len=s.size();cal_alpha(s,len);print_times();create_HT();encode_HT(HTroot,"");print_hfcode();encode_Text(b);decode_Text(c);return 0; }

    實驗用測試數據和相關結果分析

    Test 1 The quick brown fox jumps over the lazy dog.Test 2 aaaaaTest 3 bbcbaaaad
    • 結果分析:特例普例都能通過,起飛,更長文本的不好截圖,在這里不放了

    實驗總結

    • stl 雀實太好使了xdm,當時一看Huffman的建樹方式一下就想到了priority_queue了,用起來太爽了,map也為編碼提供了方便
    • 在程序的編寫過程中,Huffman編碼方式確實讓我感覺非常神奇
    • 文件的讀寫操作都忘了,現查的資料,正好復習一下TuT

    總結

    以上是生活随笔為你收集整理的数据结构实验三:Huffman树及Huffman编码的算法实现的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。