哈夫曼编码 wustOJ

来源:互联网 发布:华龙点金手机交易软件 编辑:程序博客网 时间:2024/06/01 07:20

1010: 哈夫曼编码

Time Limit: 1 Sec  Memory Limit: 65535 MB  64bit IO Format: %lld
Submitted: 19  Accepted: 3
[Submit][Status][Web Board]

Description

(1)首先构造哈夫曼树,原则是左孩子结点权值小于右孩子权值,如果结点权值有相等的,按照先生成的结点在左边,后生成的结点在右边
(2)对字符进行编码并解码。

Input

包含多组测试数据。每组测试数据包含4行。
第一行是一个字符串,表示字符集(大于1小于100);第二行是字符集中每个字符对应的权值,每个权值均大于1小于1000;第三行是一个待编码的字符串(不超过1000个字符);第四行是一个编码后的字符串(不超过10000),需要解码。

Output

每组测试用例需要输出两行:第一行是对输入的第三行的编码;第二行是对输入的第四行的解码。

Sample Input 

CAST;2 4 2 3 3CAST;1101000

Sample Output

110101110001CAT

链接 http://acm.wust.edu.cn/problem.php?cid=1148&pid=9

OJ小作业  很久以前第一次听说哈夫曼树问了一下煞笔室友   听他很不屑地说  只是一个贪心而已  我也就没怎么在意

最近李总上课点名不得不去上一下   可惜也只是到那里发了一下呆  点了一下到就过去了    他在讲哈夫曼编码的时候我也没去听

搞得我刚开始看到这题的时候有点小蒙蔽   还好数据比较水   不然估计要卡很长时间 (因为完全是我根据以前的知识xjb搞的  还好还好是一A

下面是源码+注解    (因为完全是自己看了远离后搞得   可能有点烦........



#include <algorithm>#include <cmath>#include <cstdio>#include <cstring>#include <iostream>#include <queue>#include <stack>#define root tree[id]#define leson tree[ldir]#define rison tree[rdir]using namespace std;const int maxn = 104;int len, all_time;int tree_root;//根节点char to_c[maxn];//由节点的值转化为字符char tar[maxn * 100];char tar_ch;//当前目标字符char output[maxn];//输出数组bool flag;//标记  如果已经输出就直接返回struct node {    int lson, rson;    int tim;//结点生成时间  所有原结点初始化为0    int order;//节点编号    int val;//结点的值    bool operator<(const node& a) const    {        if (val != a.val)            return val > a.val;        if (tim != a.tim)            return tim > a.tim;        return order > a.order;    }//按照题意出队};priority_queue<node> que;node tree[maxn << 2];int CreatTree(){    node ta, tb;    int id;    while (que.size() > 1) {        ta = que.top();        que.pop();        tb = que.top();        que.pop();        id = len + all_time;        root.lson = ta.order;        root.rson = tb.order;        root.val = ta.val + tb.val;        root.order = id;        root.tim = all_time++;        que.push(root);        // printf("%d %d\n",ta.order,tb.order);    }//取出两个节点并合并再入队   最后剩余的便是根节点    ta = que.top();    que.pop();    return ta.order;}void lock(int id, int dep){    if (flag)//若已经输出过了   就直接返回        return;    int ldir = root.lson, rdir = root.rson;    if (ldir) {        output[dep] = '0';        lock(ldir, dep + 1);    }    if (rdir) {        output[dep] = '1';        lock(rdir, dep + 1);    }    if (!ldir && !rdir && to_c[root.order] == tar_ch) {  //确保该结点为叶子结点也可以省点时间        for (int i = 0; i < dep; i++)            putchar(output[i]);        flag = true;//标记为true    }}int unlock(int index){    int id = tree_root;    while (root.lson || root.rson) {        if (tar[index] == '0')  // 0 向左 1向右            id = root.lson;        else            id = root.rson;        index++;    }    putchar(to_c[root.order]);    return index;//返回转化后的index}int main(){    while (scanf("%s", to_c + 1) != EOF) {        len = strlen(to_c + 1);        for (int id = 1; id <= len; id++) {            scanf("%d", &root.val);            root.order = id;            root.tim = 0;            root.lson = root.rson = 0;            que.push(root);        }        all_time = 1;        tree_root = CreatTree();        // printf("root: %d\n",tree_root);        // for(int id=1;id<=tree_root;id++)        //    printf("order: %d  val: %d  lson: %d  rson:%d\n",root.order,root.val,root.lson,root.rson); //可取消注释查看建树是否正确        scanf("%s", tar);        int tar_len = strlen(tar);        for (int i = 0; i < tar_len; i++) {            tar_ch = tar[i];            flag = false;            lock(tree_root, 0);        }        puts("");        scanf("%s", tar);        tar_len = strlen(tar);        int i = 0;        while (i < tar_len)            i = unlock(i);        puts("");    }    return 0;}

因为怎么说也是面对其他所有学生的作业

所以数据有点。。。最后被我水过去了

如果有什么好一点的做法可以讨论一下

还有的话    我到现在也没去学手写  优先队列  去年煞笔室友给我手写了一个后我还惊为天人   当时只是一知半解   只是看懂了  也没有去详细解析   最近抽点时间看看吧


0 0
原创粉丝点击