• poj1521


    霍夫曼编码,建树

    #include <cstdio>
    #include <cstring>
    #include <queue>
    using namespace std;
    
    #define MAX_LENGTH 1005
    #define MAX_ASCII 205
    #define MAX_CHAR_CNT 300
    
    struct Elem
    {
        int pos;
        int cnt;
        Elem()
        {}
        Elem(int pp, int cc): pos(pp), cnt(cc)
        {}
    };
    
    struct Node
    {
        int left_child;
        int right_child;
        int count;
    }node[MAX_CHAR_CNT];
    
    bool vis[MAX_CHAR_CNT];
    char text[MAX_LENGTH];
    int occurence_count[MAX_ASCII];
    int node_cnt;
    int original_length;
    int ans;
    int char_cnt;
    
    bool operator < (const Elem &a, const Elem &b)
    {
        return a.cnt > b.cnt;
    }
    
    void add_char(char ch)
    {
        int asc = (int)ch;
        occurence_count[asc]++;
    }
    
    void add_node(int cnt)
    {
        node[node_cnt].count = cnt;
        node[node_cnt].left_child = -1;
        node[node_cnt].right_child = -1;
        node_cnt++;
    }
    
    void count_char()
    {
        memset(occurence_count, 0, sizeof(occurence_count));
        for (int i = 0; text[i]; i++)
        {
            add_char(text[i]);
        }
        node_cnt = 0;
        for (int i = (int)'A'; i <= (int)'Z'; i++)
        {
            if (occurence_count[i])
            {
                add_node(occurence_count[i]);
            }
        }
        if (occurence_count[(int)'_'])
            add_node(occurence_count[(int)'_']);
        original_length = strlen(text) * 8;
        char_cnt = node_cnt;
    }
    
    void build_tree()
    {
        priority_queue<Elem> pq;
        memset(vis, 0, sizeof(vis));
        for (int i = 0; i < node_cnt; i++)
            pq.push(Elem(i, node[i].count));
        while (pq.size() > 1)
        {
            Elem a = pq.top();
            pq.pop();
            Elem b = pq.top();
            pq.pop();
            node[node_cnt].left_child = a.pos;
            node[node_cnt].right_child = b.pos;
            node[node_cnt].count = a.cnt + b.cnt;
            pq.push(Elem(node_cnt, a.cnt + b.cnt));
            node_cnt++;
            vis[a.pos] = true;
            vis[b.pos] = true;
        }
    }
    
    void dfs(int id, int depth)
    {
        if (node[id].left_child == -1 && node[id].right_child == -1)
        {
            ans += node[id].count * depth;
            return;
        }
        if (node[id].left_child != -1)
            dfs(node[id].left_child, depth + 1);
        if (node[id].right_child != -1)
            dfs(node[id].right_child, depth + 1);
    }
    
    int main()
    {
        while (scanf("%s", text), strcmp(text, "END"))
        {
            count_char();
            if (char_cnt == 1)
            {
                printf("%d %d 8.0
    ", original_length, original_length / 8);
                continue;
            }
            build_tree();
            ans = 0;
            dfs(node_cnt - 1, 0);
            printf("%d %d %.1f
    ", original_length, ans, original_length * 1.0 / ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    统计创建对象个数
    动手动脑
    开学第一周心得
    放假第五周总结
    放假第四周总结
    第一周总结
    04-异常处理-动手动脑
    03-继承与多态-动手动脑
    02-类和对象-跟踪类对象创建个数
    02-类和对象-动手动脑
  • 原文地址:https://www.cnblogs.com/rainydays/p/3273574.html
Copyright © 2020-2023  润新知