Haffman编码

时间限制:1000 ms  |  内存限制:65535 KB
难度:3
 
描述

哈弗曼编码大家一定很熟悉吧(不熟悉也没关系,自己查去。。。)。现在给你一串字符以及它们所对应的权值,让你构造哈弗曼树,从而确定每个字符的哈弗曼编码。当然,这里有一些小规定:

1.规定哈弗曼树的左子树编码为0,右子树编码为1;

2.若两个字符权值相同,则ASCII码值小的字符为左孩子,大的为右孩子;

3.创建的新节点所代表的字符与它的左孩子的字符相同;

4.所有字符为ASCII码表上32-96之间的字符(即“ ”到“`”之间的字符)。

 
输入
输入包含多组数据(不超过100组)
每组数据第一行一个整数n,表示字符个数。接下来n行,每行有一个字符ch和一个整数weight,表示字符ch所对应的权值,中间用空格隔开。
输入数据保证每组测试数据的字符不会重复。
输出
对于每组测试数据,按照输入顺序输出相应的字符以及它们的哈弗曼编码结果,具体格式见样例。
样例输入
3
a 10
b 5
c 8
4
a 1
b 1
c 1
d 1
样例输出
a:0
b:10
c:11
a:00
b:01
c:10
d:11

注意题目要求是按照按照输入顺序输出相应的字符以及它们的哈弗曼编码结果

#include <iostream>
#include <queue>
#include <string>
#include <algorithm>
#include <vector>
#include <cstdio>
#include <sstream>
using namespace std; struct HuffManTree;
struct HuffManTreeCmp;
typedef HuffManTree* HuffManTreePtr;
typedef priority_queue<HuffManTreePtr,vector<HuffManTreePtr>,HuffManTreeCmp> HuffManQueue; struct HuffManTree{
int freq;
char key;
HuffManTree *left,*right;
HuffManTree(int freq_ = , char key_='\0'):freq(freq_),key(key_),left(NULL),right(NULL){}
}; struct HuffManTreeCmp{
bool operator()(const HuffManTreePtr &a, const HuffManTreePtr &b)
{
if(a->freq !=b->freq) return a->freq > b->freq;
else return a->key > b->key;
return a->freq > b->freq;
}
}; HuffManTree* huffman(HuffManQueue& huffmanQueue){
while(huffmanQueue.size() > ){
HuffManTree *leftNode = huffmanQueue.top(); huffmanQueue.pop();
HuffManTree *rightNode = huffmanQueue.top();huffmanQueue.pop();
if(leftNode->freq == rightNode->freq && leftNode->key > rightNode->key) swap(leftNode->key,rightNode->key);
HuffManTree *node= new HuffManTree(leftNode->freq+rightNode->freq,leftNode->key);
node->left = leftNode;node->right = rightNode;
huffmanQueue.push(node);
}
return huffmanQueue.top();
} void print_huffman(vector<string>& res,HuffManTree *root, string code=""){
if(NULL == root) return;
if(root->left) code+='';
print_huffman(res,root->left,code);
if(!root->left && ! root->right){
string tmpRes(,root->key);
tmpRes+=":"+code;
res.push_back(tmpRes);
}
code = code.substr(,code.length()-);
if(root->right) code+='';
print_huffman(res,root->right,code);
} int main(){
int n;
while(cin >> n){
HuffManQueue huffmanQueue;
vector<char> record;
cin.ignore();
for(int i = ; i < n; ++ i){
string input;
getline(cin,input);
char ch = input[];
int freq = atoi(input.substr().c_str()) ;
record.push_back(ch);
huffmanQueue.push(new HuffManTree(freq,ch));
}
HuffManTree *root = huffman(huffmanQueue);
vector<string> res;
print_huffman(res,root);
for(int i = ; i< record.size(); ++ i){
for(int j = ; j < res.size(); ++ j){
if(res[j][]== record[i]){
cout<<res[j]<<endl;
break;
}
}
}
}
}

ACM Haffman编码的更多相关文章

  1. Haffman编码(haffman树)

    Haffman编码 时间限制:1000 ms  |  内存限制:65535 KB 难度:3   描述 哈弗曼编码大家一定很熟悉吧(不熟悉也没关系,自己查去...).现在给你一串字符以及它们所对应的权值 ...

  2. java实现Haffman编码

    1.先创建一个树节点类(泛型类),为了方便使用集合的排序方法,泛型类要实现泛型接口Comparable,代码如下 package com.hjp.huffman; /** * Created by J ...

  3. Haffman编码

    Huffman树又称为最优树,是一种带权路径最短的树. 一.带权路径 在一棵树中我们把一个节点到另一个节点之间的通路叫做路径,在路径中每经过一个节点路径的长度就加一.如果对一个节点附上权值,则该节点的 ...

  4. 转载一篇关于unicode字符编码的文章

    很久很久以前,有一群人,他们决定用8个可以开合的晶体管来组合成不同的状态,以表示世界上的万物.他们认为8个开关状态作为原子单位很好,于是他们把这称为"字节". 再后来,他们又做了一 ...

  5. Python 学习之进制与编码

    进制 日常生活中,我们最熟悉的数据就是十进制计数.它的数值部分由十个不同的数字符号0.1.2.3.4.5.6.7.8.9来表示,我们把这些数字符号叫做数码,表示十种不同的状态.数码处于不同的位置(或数 ...

  6. Ansi,UTF8,Unicode,ASCII编码的差别

    近日须要不同的编码,关于上述编码,一直迷迷糊糊,查了些资料,总算大致了解了,以下全是从网上搜来的: 1.  ASCII和Ansi编码    字符内码(charcter code)指的是用来代表字符的内 ...

  7. 文件压缩小项目haffman压缩

    文件压缩的原理: 文件压缩总体可以分为有损压缩和无损压缩两类,有损压缩是指对mp3等格式的文件,忽略一些无关紧要的信息,只保留一些关键的信息,但并不因此影响用户对于这些mp3格式文件的体验度,无损压缩 ...

  8. Ansi,UTF8,Unicode,ASCII编码的区别 ---我看完了 明白了很多

    来自:http://blog.csdn.net/xiongxiao/article/details/3741731 ------------------------------------------ ...

  9. JPEG编码(二)

    来自CSDN评论区http://bbs.csdn.net/topics/190980 1. 色彩模型 JPEG 的图片使用的是 YCrCb 颜色模型, 而不是计算机上最常用的 RGB. 关于色彩模型, ...

随机推荐

  1. jquery文件上传控件 Uploadify 问题记录

    Uploadify v3.2.1 首先引用下面的文件 <!--上传控件 uploadify--> <script type="text/javascript" s ...

  2. Linux SNMP oid

    http://www.debianadmin.com/linux-snmp-oids-for-cpumemory-and-disk-statistics.html

  3. 14.模板方法模式(Template Method)

    using System; namespace ConsoleApplication7 { class Program { /// <summary> /// 模板方法模式——在一个抽象类 ...

  4. SVN的忽略和只读使用方法学习记录

    前言,先扯几句.最近学了GIT,虽然很肤浅,但是也算是用上了分布式版本管理控制系统.Linus很牛,他也很厌烦SVN,而我看这些都是工具,是否拿来使用主要看是否顺手.我赞同分布式版本管理控制,它有诸多 ...

  5. HDU5792 World is Exploding(树状数组)

    一共6种情况,a < b且Aa < Ab, c < d 且Ac > Ad,这两种情况数量相乘,再减去a = c, a = d, b = c, b = d这四种情况,使用树状数组 ...

  6. Bat脚本实现MySQL数据库SQL文件备份

    @echo offecho 在线兑奖系统自动备份脚本(请勿关闭) 联系人:  电话::loopset /a "FDate=%date:~,4%%date:~5,2%%date:~8,2%&q ...

  7. java调用shell获取返回值

    转自:http://blog.csdn.net/tengdazhang770960436/article/details/12014839 1.shell文件return.sh echo 1 echo ...

  8. Android开发如何去除标题栏title(转)

    去除标题栏title其实非常简单,他有两种方法,一种是在代码中添加,另一种是在AndroidManifest.xml中添加: 1.在代码中实现:在此方法setContentView(R.layout. ...

  9. JS 正则表达式详解

    在此提供相关的链接,请访问: http://www.cnblogs.com/dolphinX/p/3486214.html http://www.cnblogs.com/dolphinX/p/3486 ...

  10. javase基础笔记4——异常/单例和类集框架

    继承 extends final关键 多态 是在继承的基础上 接口 interface 异常 exception 包的访问可控制权限 private default protect public 异常 ...