【哈夫曼树】hdu 1053

来源:互联网 发布:实施网络攻击的前提 编辑:程序博客网 时间:2024/06/06 07:50

裸的哈夫曼树。开一个优先队列存节点,按出现频率从小到大取出。

注意所有字符相同的特例!

#include <map>#include <set>#include <list>#include <queue>#include <deque>#include <stack>#include <string>#include <time.h>#include <cstdio>#include <math.h>#include <iomanip>#include <cstdlib>#include <limits.h>#include <string.h>#include <iostream>#include <fstream>#include <algorithm>using namespace std;#define LL long long#define MIN INT_MIN#define MAX INT_MAX#define PI acos(-1.0)#define FRE freopen("input.txt","r",stdin)#define FF freopen("output.txt","w",stdout)#define N 1005priority_queue<int,vector<int>,greater<int> > pp;char str[N];int d[100];int main () {FRE;    int n;    while (scanf("%s",str) != -1) {        if (strcmp(str,"END") == 0) break;        int i;        while (!pp.empty()) pp.pop();        memset(d,0,sizeof(d));        int len = strlen(str);        for (i = 0; i < len; i++) {            d[str[i]]++;        }        int ans = 0;        int cnt = 0;        for (i = 0; i < 100; i++) {            if (d[i]) {                cnt++;                pp.push(d[i]);            }        }        while (pp.size() != 1) {            int a,b;            a = pp.top();            pp.pop();            b = pp.top();            pp.pop();            ans += (a + b);            pp.push(a + b);        }        if (cnt == 1) {            printf("%d %d 8.0\n",len*8,len);            continue;        }        printf("%d %d %.1f\n",len*8,ans,(double)len*8.0/(double)ans);    }    return 0;}

建树版本

#include <map>#include <set>#include <list>#include <queue>#include <deque>#include <stack>#include <string>#include <time.h>#include <cstdio>#include <math.h>#include <iomanip>#include <cstdlib>#include <limits.h>#include <string.h>#include <iostream>#include <fstream>#include <algorithm>using namespace std;#define LL long long#define MIN INT_MIN#define MAX INT_MAX#define PI acos(-1.0)#define FRE freopen("input.txt","r",stdin)#define FF freopen("output.txt","w",stdout)#define N 1005char str[N];struct node {    int data;//字母出现频率    int dep;//该节点深度    node * L, * R;//左右节点    node(){        data = 0;        dep = 0;        L = NULL;        R = NULL;    }};//重载小于号bool operator < (node a,node b) {        return a.data > b.data;}priority_queue<node> pp;int num[100];int sum;//建树void Build () {    node *p, *q, *t, root;    while (pp.size() != 1) {        p = new node;        *p = pp.top();        pp.pop();        q = new node;        *q = pp.top();        pp.pop();        t = new node;        t->data = p->data + q->data;        t->L = p;        t->R = q;        pp.push(*t);    }    root = pp.top();    pp.pop();    queue<node> qq;    qq.push(root);    root.dep = 0;    sum = 0;    while (!qq.empty()) {        node x = qq.front();        qq.pop();        if (x.L != NULL) {            x.L->dep = x.dep + 1;            qq.push(*(x.L));        }        if (x.R != NULL) {            x.R->dep = x.dep + 1;            qq.push(*(x.R));        }        if (x.L == NULL && x.R == NULL) {            sum += x.dep * x.data;        }    }}int main () {    while (scanf("%s",str)) {        if (strcmp(str,"END") == 0) break;        while (!pp.empty()) pp.pop();        memset(num,0,sizeof(num));        int i,j;        int len = strlen(str);        for (i = 0; i < len; i++) {            num[str[i]]++;        }        int cnt = 0;        for (i = 0; i < 100; i++) {            if (num[i]) {                cnt++;                node tmp;                tmp.data = num[i];                pp.push(tmp);            }        }        if (cnt == 1) {            printf("%d %d 8.0\n",8*num[str[0]],len);            continue;        }        Build();        double ans = (double)(len*8) / (double)sum;        printf("%d %d %.1f\n",len * 8, sum, ans);    }    return 0;}


原创粉丝点击