hdu1053 Entropy(哈夫曼樹)
阿新 • • 發佈:2019-02-06
複習了一天哈夫曼樹。。。
去年只是學了哈夫曼的構建,但不懂這樹的含義,今天想了好久,真的好厲害一棵樹啊!
一個普通的字串,竟然可以轉變為帶權值的樹。我許久不能理解的是為什麼字元出現次數可以用權值來表達,現在想這權值似乎就是為次數而建立的。。。有了很深的體會但腦子抽住了,改天再好好談談對哈夫曼的看法吧。
本題由於不要求寫出編碼,所以用優先佇列統計,權值小的權值優先加起來,相當於多了權值多的位元組,出現次數少的所佔位元組越多,加的次數也就越多,正好符合哈夫曼的原理。
#include <stdio.h> #include <algorithm> #include <iostream> #include <queue> #include <string.h> using namespace std; const int N = 50; const int INF = 1000000; struct node { int w; friend bool operator < (const node &a, const node &b) { return a.w > b.w; } }; int main() { // freopen("in.txt", "r", stdin); char s[5000]; int a[30]; int ans; while(~scanf("%s", s)) { ans = 0; if(!strcmp("END", s)) break; //比較字串,相等輸出的是0! int len = strlen(s); memset(a, 0, sizeof(a)); for(int i = 0; i < len; i ++) { if(s[i] == '_') a[0] ++; else a[s[i] - 'A' + 1] ++; } priority_queue <node> q; for(int i = 0; i < 27; i ++) { node tmp; tmp.w = a[i]; if(tmp.w) q.push(tmp); } if(q.size() == 1) ans = len;//只有一種字元,每個字元一個位元組,共len個 else { while(q.size() > 1) { node tmp2, tmp3, tmp0; tmp2 = q.top(); q.pop(); tmp3 = q.top(); q.pop(); tmp0.w = tmp2.w + tmp3.w; ans += tmp2.w + tmp3.w; q.push(tmp0); } } printf("%d %d %.1lf\n", len * 8, ans, (double)(len * 8) / ans); } return 0; }