描述
写一个哈夫曼码的编/译码系统,要求能对要传输的报文进行编码和解码。构造哈夫曼树时,权值小的放左子树,权值大的放右子树,编码时右子树编码为1,左子树编码为0.
输入
输入表示字符集大小为n(n <= 100)的正整数,以及n个字符和n个权值(正整数,值越大表示该字符出现的概率越大);
输入串长小于或等于100的目标报文。
输入串长小于或等于100的目标报文。
输出
经过编码后的二进制码,占一行;
以及对应解码后的报文,占一行;
最后输出一个回车符。
以及对应解码后的报文,占一行;
最后输出一个回车符。
输入样例
5 a b c d e 12 40 15 8 25
bbbaddeccbbb
bbbaddeccbbb
输出样例
00011111110111010110110000
bbbaddeccbbb
bbbaddeccbbb
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAXBIT 100
#define MAXNODE 1000
#define MAXNUM 1000000
#define MAXWEIGHT 1000
using namespace std;
/*编码结构体*/
typedef struct
{
int bit[MAXBIT];
int start;
}HCodeType;
/*结点结构体*/
typedef struct
{
int weight;
int parent;
int lchild;
int rchild;
char value;
}HNodeType;
void HuffmanTree(HNodeType HuffNode[], int n)
{
int i, j;
//结点初始化
for(i = 0; i < 2*n-1; i++)
{
HuffNode[i].weight = 0;
HuffNode[i].parent = -1;
HuffNode[i].lchild = -1;
HuffNode[i].rchild = -1;
HuffNode[i].value = -1;
}
//叶子结点的编码和权重
for(i = 0; i < n; i++)
cin >> HuffNode[i].value;
for(i = 0; i < n; i++)
cin >> HuffNode[i].weight;
for(i = 0; i < n-1; i++)
{
//记录最小的两个权重
int m1, m2;
m1 = m2 = MAXWEIGHT;
//记录相应的下标
int x1, x2;
x1 = x2 = 0;
for(j = 0; j < n+i; j++)
{
if((HuffNode[j].weight<m1) && (HuffNode[j].parent==-1))
{
m2 = m1;
x2 = x1;
m1 = HuffNode[j].weight;
x1 = j;
}
else if((HuffNode[j].weight<m2) && (HuffNode[j].parent==-1))
{
m2 = HuffNode[j].weight;
x2 = j;
}
}
HuffNode[x1].parent = n+i;
HuffNode[x2].parent = n+i;
HuffNode[n+i].weight = HuffNode[x1].weight+HuffNode[x2].weight;
HuffNode[n+i].lchild = x1;
HuffNode[n+i].rchild = x2;
//printf ("x1.weight and x2.weight in round %d: %d, %d\n", i+1, HuffNode[x1].weight, HuffNode[x2].weight);
}
}
/*解码*/
void decoding(char str[], HNodeType hufTree[], int n)
{
int num = 2*n-1;//结点个数
int i =0;
int temp;
while(i < (int)strlen(str))
{
temp = num-1;//根节点下标
while((hufTree[temp].lchild!=-1)&&(hufTree[temp].rchild!=-1))
{
if(str[i] == '0')
temp = hufTree[temp].lchild;
else
temp = hufTree[temp].rchild;
i++;
}
printf("%c", hufTree[temp].value);
}
}
int main()
{
HNodeType HuffNode[MAXNODE];
HCodeType HuffCode[MAXBIT], cd;
int n, i;
scanf("%d", &n);
HuffmanTree(HuffNode, n);
for(i = 0; i < n; i ++)
{
cd.start = n-1;
int cur = i;
int p = HuffNode[cur].parent;
while(p!=-1)
{
if(HuffNode[p].lchild == cur)
cd.bit[cd.start] = 0;
else
cd.bit[cd.start] = 1;
//printf("%d: %d\n", i ,cd.bit[cd.start]);
cd.start--;
cur = p;
p = HuffNode[cur].parent;
}
for(int j = cd.start+1; j<n; j++)
HuffCode[i].bit[j] = cd.bit[j];
HuffCode[i].start = cd.start;
}
/*
for (int i=0; i<n; i++)
{
printf ("%d 's Huffman code is: ", i);
for (int j=HuffCode[i].start+1; j < n; j++)
{
printf ("%d", HuffCode[i].bit[j]);
}
printf(" start:%d",HuffCode[i].start);
printf ("\n");
}
*/
char code[1000];
scanf("%s", code);
for(i = 0; i < (int)strlen(code); i++)
{
for(int j = 0; j < n; j++)
{
if(code[i] == HuffNode[j].value)
{
//printf("%c 的编码是", code[i]);
for(int k = HuffCode[j].start+1; k < n; k++)
printf("%d", HuffCode[j].bit[k]);
//cout << endl;
}
}
}
printf("\n");
// char decode[1000];
// scanf("%s", decode);
// decoding(decode, HuffNode, n);
cout << code << endl;
return 0;
}