概述
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
思路:使用静态链表组织数据
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct node
{
char data; // 数据
int w, l, r, p; // w为权重,l为左孩子,r为右孩子,p为父节点
} tree[100];
int INF = 1e9+7; // 设置最大值
int main()
{
char str[100];
int i, j, num, n, m, w1, w2, k1, k2, p, sum, f[100];
while(~scanf("%s", str))
{
memset(f, 0, sizeof(f)); // 初始化用来检查的f数组
n = strlen(str);
m = 0;
for (i = 0; i < n; i++) // 遍历字符串
{
for (j = 0; j < m; j++)
{
if (tree[j].data == str[i]) // 若在已初始化的结点中存在该字符,则该节点权值+1
{
tree[j].w++;
break;
}
}
if (j == m) // 若已初始化的结点中不存在该字符,则生成一个新的结点
{
tree[m].data = str[i];
tree[m].w = 1;
tree[m].l = tree[m].r = tree[m].p = -1;
m++;
}
}
for (i = m; i < 2*m-1; i++) // 将其他结点依次输出
{
w1 = w2 = INF; // 初始化为最大值
k1 = k2 = -1; // 初始化
for (j = 0; j < i; j++) // 遍历带权结点
{
if (f[j]) // 若该结点使用过,则跳过
{
continue;
}
if (tree[j].w < w1) // 选择两个权值最小的结点,其中w1比w2小
{
w2 = w1;
k2 = k1;
w1 = tree[j].w;
k1 = j;
}
else if (tree[j].w < w2)
{
w2 = tree[j].w;
k2 = j;
}
}
// 找到权值最小的两个结点
f[k1] = f[k2] = 1; // 标记已使用
// 创建新的结点
tree[i].w = tree[k1].w + tree[k2].w;
tree[i].l = k1;
tree[i].r = k2;
tree[i].p = -1;
// 连接三个结点
tree[k1].p = tree[k2].p = i;
}
// 计算
sum = 0;
for (i = 0; i < m; i++)
{
num = 0;
p = tree[i].p;
while(p != -1)
{
num++;
p = tree[p].p;
}
sum += num*tree[i].w;
}
printf("%d %d %.1fn", n*8, sum, n*8.0/sum);
}
return 0;
}
最后
以上就是踏实花生为你收集整理的SDUTOJ 3345 - 数据结构实验之二叉树六:哈夫曼编码的全部内容,希望文章能够帮你解决SDUTOJ 3345 - 数据结构实验之二叉树六:哈夫曼编码所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复