HDU1053 - Entropy (哈夫曼树)

题目链接

思路

纯数据结构。

代码

#include <iostream>
#include <cstdio>
#include <map>
#include <queue>
#include <cstring>

using namespace std;

struct node
{
    char ch;
    int num;
    int ls, rs;
} tree[100];
struct cmp
{
    bool operator()(int &a, int &b)
    {
        return tree[a].num>tree[b].num;
    }
};
char text[1000];

void traversal(int root, int count, map<char, int> & table)
{
    if(!tree[root].ls&&!tree[root].rs)
    {
        table[tree[root].ch] = count;
    }
    else
    {
        if(tree[root].ls) traversal(tree[root].ls, count+1, table);
        if(tree[root].rs) traversal(tree[root].rs, count+1, table);
    }
}

void slove()
{
    map<char ,int> count;
    int nCount = 0;
    int len = strlen(text);

    for(int i=0; i<len; i++) count[text[i]]++;
    priority_queue<int, vector<int>, cmp> qu;
    for(map<char, int>::iterator it=count.begin(); it!=count.end(); it++)
    {
        tree[++nCount].ch = (*it).first;
        tree[nCount].num = (*it).second;
        tree[nCount].ls = tree[nCount].rs = 0;
        qu.push(nCount);
    }

    if(qu.size()==1)
    {
        printf("%d %d %.1f\n", len*8, len, 8.0);
    }
    else
    {
        int a, b;
        while(!qu.empty())
        {
            a = qu.top();
            qu.pop();
            if(qu.empty()) break;
            b = qu.top();
            qu.pop();
            tree[++nCount].num = tree[a].num + tree[b].num;
            tree[nCount].ls = a;
            tree[nCount].rs = b;
            qu.push(nCount);
        }
        map<char, int> table;
        traversal(nCount, 0, table);
        int sum = 0;
        for(map<char, int>::iterator it=count.begin(); it!=count.end(); it++)
        {
            sum += (table[(*it).first]*((*it).second));
        }
        printf("%d %d %.1f\n", len*8, sum, (double)len*8/sum);
    }
}

int main()
{
    while(gets(text))
    {
        if(strcmp(text, "END")==0) break;
        else
        {
            slove();
        }
    }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值