您的位置:首页 > 理论基础 > 数据结构算法

数据结构实验之二叉树六:哈夫曼编码

2016-10-26 22:10 197 查看


数据结构实验之二叉树六:哈夫曼编码

Time Limit: 1000MS Memory Limit: 65536KB

Submit Statistic


Problem Description

字符的编码方式有多种,除了大家熟悉的ASCII编码,哈夫曼编码(Huffman Coding)也是一种编码方式,它是可变字长编码。该方法完全依据字符出现概率来构造出平均长度最短的编码,称之为最优编码。哈夫曼编码常被用于数据文件压缩中,其压缩率通常在20%~90%之间。你的任务是对从键盘输入的一个字符串求出它的ASCII编码长度和哈夫曼编码长度的比值。


Input

 输入数据有多组,每组数据一行,表示要编码的字符串。


Output

 对应字符的ASCII编码长度la,huffman编码长度lh和la/lh的值(保留一位小数),数据之间以空格间隔。


Example Input

AAAAABCD
THE_CAT_IN_THE_HAT



Example Output

64 13 4.9
144 51 2.8


思路:

每个字符ASCII码是占8个字节的。所以长度就是字符数×8;

对于哈夫曼编码就是哈夫曼树一样。

对于第一个串每个字符出现的长度是5111.

那么第一次出来2 队列变成5 2 1;

然后第二次出来3 队列变成5 3;

然后最后出来8  队列剩下一个8;

所以哈夫曼编码长度就是2+3+8=13;

这里是用一个优先队列来解决的,不会的可以放进一个数组里,然后你每次找一个数组中最小的数加上,放上新的数就可以了。

对于数据比较大的就用堆来实现。

这里用来记录出现的字符集合是用哈希的思想来实现的。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int MAXN=100+10;
char s[MAXN];
int ha[200];
int sum[200];
int main()
{
int la,lh,l;
int i;
while(~scanf("%s",s))
{

memset(ha,0,sizeof(ha));
l=strlen(s);
la=l*8;
priority_queue<int,vector<int>,greater<int> >q;
int cnt=0;
for(i=0; i<l; ++i)
{
if(!ha[s[i]])sum[cnt++]=s[i];
ha[s[i]]++;
}
for(i=0;i<cnt;++i)q.push(ha[sum[i]]);
lh=0;
while(!q.empty())
{
int k1=q.top();
q.pop();
if(!q.empty())
{
int k2=q.top();
q.pop();
lh+=k1+k2;
q.push(k1+k2);
}
}
printf("%d %d %.1lf\n",la,lh,la*1.0/lh);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息