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

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

Time Limit: 1000 ms Memory Limit: 65536 KiB

Submit Statistic

Problem Description

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

Input

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

Output

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

Sample Input

AAAAABCD
THE_CAT_IN_THE_HAT

Sample Output

64 13 4.9
144 51 2.8

Hint

 

Source

xam


哈夫曼编码在离散数学里有提及,其原理是

哈夫曼提出构造最优前缀码的贪心算法,由此产生的编码方案称为哈夫曼编码。其构造步骤如下:

难点在于哈夫曼二叉树的建立,而哈夫曼编码是以自底向上的方式构造表示最优先前缀码的二叉树,这里需要用到优先队列。用到了STL标准函数库中的优先队列函数:priority_queue<int> qi

此函数是在优先队列中,优先级高的元素优先出队列,STl标准库中默认使用的是小于操作符来确定它们之间的关系。所以当需求是优先级低的元素优先出队列的话直接调用priority_queue<int>qi函数即可。但是如果需求是根据大于操作符来确定之间的优先关系,就需要加上二级参数。即调用:priority_queue<int,vector<int>,greater<int> >qi2;当然这个函数里面的greater<int>的参数部分可以根据需要来进行编写。

本题调用优先队列函数和队列函数集可以写出很简洁的代码。

ASCII码对照表和部分语言运算符优先级点我​​​​​​​

AC代码:

#include<bits/stdc++.h>//万能头
using namespace std;
int main()
{
	char s[10010];
	int b[200];
	int al;
	while(~scanf("%s",s))
	{
		priority_queue<int,vector<int>,greater<int> >q;//调用优先队列函数,因为需要优先输出等级高的元素,所以采用第二种函数。
		int n;
		n=strlen(s);//记录输入字符串的长度
		memset(b,0,sizeof(b));//记得清空b数组,b数组的作用是用来根据ASCII码来确定各个字符出现的频率的过渡数组。
		al=n*8;//al的长度就是字符长度乘8,因为一个字符占用8个编码长度。一个编码长度就是一个bit,一个字符8bit。
		for(int i=0;i<n;i++)//确定各个字符出现的次数
		{
			b[s[i]]++;
		}
		for(int i=0;i<150;i++)//ASCII码最高到127,所以不用遍历很高
		{
			if(b[i]!=0)
			{
				q.push(b[i]);//出现就进队列
			}
		}
		int a,b;
		int c,sum=0;
		while(!q.empty())//当队列不为空的时候
		{
			a=q.top();//a等于队头元素
			q.pop();//队头元素出队列
			if(!q.empty())//a元素之后如果队列不空,那么b进行同样的操作
			{
				b=q.top();
				q.pop();
				c=a+b;//这里直接相加即可
				sum=sum+c;
				q.push(c);
			}
		}
		printf("%d %d %.1lf\n",al,sum,1.0*al/sum);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值