題目非常長,大致看了下,赤裸裸的HUFFMAN樹,是資料結構中很基礎的東西了,以前寫過求HUFFMAN編碼的程式,但是感覺這題沒有必要把HUFFMAN全部球出來,上網查了一下,找到了一種不錯的解法,是使用優先隊列來解的.
關於Huffman樹有什麼不瞭解的可以看這篇文章,講解的很詳細,http://blog.csdn.net/hairetz/archive/2009/05/05/4151866.aspx
另外優先隊列priority_queue是STL庫中的,包含在標頭檔<queue>中,會自動對新放入隊列的資料進行排序,這裡採用的是隊頭數最小的排序方式.每次取出前兩個(也就是權值最小的兩節點)構成新的節點,再放入隊列中,直到取到最後一個為止,這也符合HUFFMAN樹的構造過程..
//關於Huffman樹<br />#include <iostream><br />#include <queue><br />#include <cstdlib><br />#include <cstdio><br />#include <algorithm><br />using namespace std;<br />int cmp(const void *a,const void *b);<br />int main(){<br />string line;<br />while(1){<br />getline(cin,line);<br />if(line=="END")break;<br />priority_queue<int ,vector<int>,greater<int> > qu;<br />//對字元數組排序並將字元個數依次放入優先隊列中<br />sort(line.begin(),line.end());<br />char c=line[0];<br />int times=0;<br />for(int i=0;i<line.length();i++){<br />if(line[i]==c)times++;<br />else{<br />qu.push(times);<br />c=line[i];<br />times=1;<br />}<br />}<br />qu.push(times);<br />int oldLen=line.length()*8;<br />int newLen=0;<br />//構造Huffman樹的過程<br /> int a,b;<br />if(qu.size()==1)newLen=qu.top();<br />while(1){<br />a=qu.top();<br />qu.pop();<br />if(qu.empty())break;<br />b=qu.top();<br />qu.pop();<br />newLen+=a+b;//這一步很巧,因為編碼長度和其在樹中的層數相關<br />qu.push(a+b);<br />}<br />printf("%d %d %.1f/n",oldLen,newLen,oldLen*1.0/newLen);<br />}</p><p>return 0;<br />}