POJ 1521 哈夫曼編碼 貪心法
阿新 • • 發佈:2019-02-13
題意:給定字串,求哈夫曼編碼長和它與等長編碼的比值,比較基礎
思路:這題考查哈弗曼編碼,但其實沒必要建樹得出編碼,只需要統計哈弗曼編碼後的總碼長即可
參考了網友的題解,用到了優先權佇列維持一個從小到大的序列
第38行其實就是把越小的頻數反覆多加幾次,越大的頻率少加幾次,體現了字首碼的設計思想
Source Code
Memory: 232K | Time: 0MS |
Language: C++ | Result: Accepted |
//這題考查哈弗曼編碼,但其實沒必要建樹得出編碼,只需要統計哈弗曼編碼後的總碼長即可 #include <iostream> #include <queue> using namespace std; class mycomparison { public: bool operator() (const int& lhs, const int&rhs) const { return (lhs > rhs);//使得從小到大排序,佇列頭為最小元素,優選權佇列預設佇列頭最大 } }; int main(){ char s[500]; int count[200] = {0};//count[i]記錄ASCII碼為i的字元的個數 int i, sum, len; priority_queue<int, vector<int>, mycomparison> pq; while(cin>>s){ if(!strcmp(s,"END")){ break; } len = strlen(s); for(i = 0; i < len; i++){ count[s[i]]++; } sum = 0; for(i = 0;i < 200; i++){ if(count[i]){ pq.push(count[i]); count[i] = 0; } } while(pq.size() > 1){ int a = pq.top(); pq.pop(); int b = pq.top(); pq.pop(); sum += a + b;//其實就是把越小的頻率反覆多加幾次,越大的頻率少加幾次 pq.push(a + b); } if(!sum){ sum = len;//此時pq中只有一個元素 } while(!pq.empty()){ pq.pop(); } printf("%d %d %.1f\n",8*len,sum,double(double(8*len)/sum));//注意精度設定 } return 0; }