Description
字符的编码方式有多种,除了大家熟悉的ASCII编码,哈夫曼编码(Huffman Coding)也是一种编码方式,它是可变字长编码。该方法完全依据字符出现概率来构造出平均长度最短的编码,称之为最优编码。哈夫曼编码常被用于数据文件压缩中,其压缩率通常在20%~90%之间。你的任务是对从键盘输入的一个字符串求出它的ASCII编码长度和哈夫曼编码长度的比值。
Input
输入数据有多组,每组数据一行,表示要编码的字符串。
Output
对应字符的ASCII编码长度la,huffman编码长度lh和la/lh的值(保留一位小数),数据之间以空格间隔。
Sample
Input
AAAAABCD
THE_CAT_IN_THE_HAT
Output
64 13 4.9
144 51 2.8
Hint
运用哈夫曼编码解法
#include<iostream>
#include <string>
#include <map>
#include <cstring>
#include <algorithm>
using namespace std;
#define maxSize 100
typedef struct Node
{
int weight;
int parent;
int lchild, rchild;
}HTNode, * HuffmanTree;
typedef char** HuffmanCode;
HuffmanTree create_HuffmanTree(int* wet, int n);
void select_minium(HuffmanTree HT, int k, int& min1, int& min2);
int min(HuffmanTree HT, int k);
void HuffmanCoding1(HuffmanTree HT, HuffmanCode& HC, int n);
bool cmd1(char* str1, char* str2);
int main()
{
string str;
while (getline(cin, str))
{
map <char, int> m;
for (auto& i : str)
{
m[i]++;
}
int j = 0;
int w[1000];
for (auto& i : m)
{
w[j] = i.second;
j++;
}
int n = j;
HuffmanCode HC = NULL;
HuffmanTree hTree = create_HuffmanTree(w, n);
HuffmanCoding1(hTree, HC, n);
sort(HC, HC + n, cmd1);
sort(w, w + n);
int lh = 0;
for (int i = 0; i < n; i++)
{
lh += w[i] * (int)strlen(HC[i]);
}
int la = (int)str.size() * 8;
float res = (float)la / (float)lh;
printf("%d %d %.1f\n", la, lh, res);
}
return 0;
}
HuffmanTree create_HuffmanTree(int* wet, int n)
{
int total = 2 * n - 1;
HuffmanTree HT = (HuffmanTree)malloc(total * sizeof(HTNode));
int i;
for (i = 0; i < n; i++)
{
HT[i].parent = -1;
HT[i].lchild = -1;
HT[i].rchild = -1;
HT[i].weight = *wet;
wet++;
}
for (; i < total; i++)
{
HT[i].parent = -1;
HT[i].lchild = -1;
HT[i].rchild = -1;
HT[i].weight = 0;
}
int min1, min2;
for (i = n; i < total; i++)
{
select_minium(HT, i, min1, min2);
HT[min1].parent = i;
HT[min2].parent = i;
HT[i].lchild = min1;
HT[i].rchild = min2;
HT[i].weight = HT[min1].weight + HT[min2].weight;
}
return HT;
}
void select_minium(HuffmanTree HT, int k, int& min1, int& min2)
{
min1 = min(HT, k);
min2 = min(HT, k);
}
int min(HuffmanTree HT, int k)
{
int i = 0;
int min;
int min_weight;
while (HT[i].parent != -1)
i++;
min_weight = HT[i].weight;
min = i;
for (; i < k; i++)
{
if (HT[i].weight < min_weight && HT[i].parent == -1)
{
min_weight = HT[i].weight;
min = i;
}
}
HT[min].parent = 1;
return min;
}
void HuffmanCoding1(HuffmanTree HT, HuffmanCode& HC, int n)
{
HC = (HuffmanCode)malloc(n * sizeof(char*));
char* code = (char*)malloc(n * sizeof(char));
code[n - 1] = '\0';
int i;
for (i = 0; i < n; i++)
{
int current = i;
int father = HT[i].parent;
int start = n - 1;
while (father != -1)
{
if (HT[father].lchild == current)
code[--start] = '0';
else
code[--start] = '1';
current = father;
father = HT[father].parent;
}
HC[i] = (char*)malloc((n - start) * sizeof(char));
strcpy(HC[i], code + start);
}
free(code);
}
bool cmd1(char* str1, char* str2)
{
return strlen(str1) > strlen(str2);
}