数据结构实验之二叉树六:哈夫曼编码
Time Limit: 1000MS Memory limit: 65536K
题目描述
字符的编码方式有多种,除了大家熟悉的ASCII编码,哈夫曼编码(Huffman Coding)也是一种编码方式,它是可变字长编码。该方法完全依据字符出现概率来构造出平均长度最短的编码,称之为最优编码。哈夫曼编码常被用于数据文件压缩中,其压缩率通常在20%~90%之间。你的任务是对从键盘输入的一个字符串求出它的ASCII编码长度和哈夫曼编码长度的比值。
输入
输入数据有多组,每组数据一行,表示要编码的字符串。
输出
对应字符的
ASCII
编码长度
la
,
huffman
编码长度
lh
和
la/lh
的值
(
保留一位小数
)
,数据之间以空格间隔。
示例输入
AAAAABCD THE_CAT_IN_THE_HAT
示例输出
64 13 4.9 144 51 2.8
数组模拟
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
using namespace std;
char c[1000000];
char d[1000000];//存储不重复的字符串
int a[1000000]; //统计相同字符个数
int b[1000000];
int k;
int cmp ( const void *a , const void *b ) //降序排列
{
return *(int *)b - *(int *)a;
}
void weight(char c[])//求每个字符的权值
{
int i, j;
k = 0;
d[0]='\0';
memset(a, -1, sizeof(a));//不能清为零,否则WA
int len = strlen(c);
for(i = 0; i<len; i++)
{
if(k == 0)
{
d[k] = c[i];
a[k] = 1;
k++;
}
else
{
int flag = 1;
for(j=0; j<k; j++)
{
if(d[j]==c[i])
{
a[j]++;
flag = 0;
break;
}
}
if(flag == 1)
{
d[k] = c[i];
a[k] = 1;
k++;
}
}
}
qsort(a, k, sizeof(a[0]), cmp);
}
int main()
{
int i, j;
while(~scanf("%s", c))
{
int len = strlen(c);
j = 0;
weight(c);
while(k-2>=0)//原数组为空则结束循环
{
b[j++] = a[k-1]+a[k-2];//取权值最小的两个相加
k--;
a[k-1] = b[j-1];//将结果插入原数组
qsort(a, k, sizeof(a[0]), cmp);
}
int s = 0;
for(i=0; i<j; i++)
{
s = s+b[i];
}
printf("%d %d %.1lf\n", len*8, s, (len*8.0)/s);
}
}
优先队列
#include <stdio.h>
#include <stdlib.h>
#include <queue>
#include <string.h>
#include <algorithm>
using namespace std;
int main()
{
priority_queue<int, vector<int>, greater<int> >q;//优先队列
//升序
int n, i, num, a, b, sum;
char c[1010];
int v[1010];
while(~scanf("%s", c))
{
sum = 0;
memset(v, 0, sizeof(v));
int n = strlen(c);
for(i=0; i<n; i++)
v[c[i]]++; //c[i]自动转化为ASCII码
for(i=0; i<200; i++)
{
if(v[i])
q.push(v[i]);
}
while(!q.empty())
{
a = q.top();
q.pop();
if(!q.empty())
{
b = q.top();
q.pop();
num = a+b;
q.push(num);
sum += num;
}
}
printf("%d %d %.1lf\n", n*8, sum, (n*8.0)/sum);
}
}