描述
写一个哈夫曼码的编/译码系统,要求能对要传输的报文进行编码和解码。构造哈夫曼树时,权值小的放左子树,权值大的放右子树,编码时右子树编码为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<stdio.h>
#include<stdlib.h>
#include<string.h>
struct node
{
char zifu;
int wet,par,lch,rch;
};
struct code
{
char data;
char cod[20];
};
typedef struct hftree
{
struct node ht[100];
int root;
}hftree,*phftree;
phftree create(int n,int w[],char f[])
{
phftree pht;
int i,j,x1=1,x2=1; //最小权值其对应的下标
int m1=10000,m2=10000; // 记录最小的权值
pht=(phftree)malloc(sizeof(hftree));
for(i=1;i<=2*n-1;i++) //n个数,即有n个叶子节点,生成的哈夫曼树有2n-1 个节点
{
pht->ht[i].par=0;
pht->ht[i].lch=0;
pht->ht[i].rch=0;
if(i<=n)
{
pht->ht[i].wet=w[i-1];
pht->ht[i].zifu=f[i-1];
}
else pht->ht[i].wet=0;
}
for(i=1;i<n;i++) //冒泡排序,找出两个最小的,插入到数组中,继续相同的操作
{
for(j=1;j<n+i;j++)
{
if(pht->ht[j].wet<m1&&pht->ht[j].par==0)
{
m2=m1;
x2=x1;
m1=pht->ht[j].wet;
x1=j;
}
else if(pht->ht[j].wet<m2&&pht->ht[j].par==0)
{
m2=pht->ht[j].wet;
x2=j;
}
}
pht->ht[x1].par=n+i;
pht->ht[x2].par=n+i;
pht->ht[n+i].lch=x1;
pht->ht[n+i].rch=x2;
pht->ht[n+i].wet=pht->ht[x1].wet+pht->ht[x2].wet;
pht->root=n+i;
m1=10000;m2=10000;
}
return pht;
}
void coding(phftree pht,struct code HC[],int root)
{
static int codelen=0,i=1; // 这里用静态 很重要,因为要进行递归
static char cd[100];
if (pht->ht[root].rch == 0) {
cd[codelen] = '\0'; // 字符串结尾的标志是'\0'
HC[i].data=pht->ht[root].zifu;
strcpy(HC[i++].cod, cd);
}
else {
cd[codelen++] = '0';
coding (pht, HC, pht->ht[root].lch);
codelen--; // 将‘\0’去掉
cd[codelen++] = '1';
coding (pht, HC, pht->ht[root].rch);
codelen--; // 将‘\0’去掉
}
}
int main()
{
phftree pht;
struct code HC[30];
int i,j,n,len,w[30]={0};
char f1[60]={'\0'},f[30]={'\0'};
char file[100]={'\0'};
char transf1[100][20]={'\0'},transf2[100]={'\0'};
scanf("%d",&n);
for(i=0;i<2*n;i++)scanf("%c",&f1[i]);
for(i=0;i<n;i++)scanf("%d",&w[i]);
for(i=0;i<n;i++)f[i]=f1[2*i+1];//输入有空格 所以这里要进行一下去除空隔的操作
getchar(); // 应为有换行,防止进入字符串
gets(file);
pht=create(n,w,f); // 创建哈夫曼树
coding(pht,HC,pht->root); // 根据哈夫曼树 对字符进行编码
for(i=0;file[i]!='\0';i++) // 这里主要是对输入的字符进行编码,根据coding函数得出的编码情况
{
for(j=1;j<=n;j++)
{
if(file[i]==HC[j].data) // 与哪个字符相等,就把字符对应的哈夫曼编码赋值给它
{
strcpy(transf1[i],HC[j].cod);
break;
}
}
}
len=strlen(file);
for(i=0;i<len;i++)// 解码过程
{
for(j=1;j<=n;j++)
{
if(strcmp(transf1[i],HC[j].cod)==0) //比较编码,相同则输出相应的数据;
{
transf2[i]=HC[j].data;
break;
}
}
}
for(i=0;i<len;i++)printf("%s",transf1[i]);
printf("\n");
for(i=0;i<len;i++)printf("%c",transf2[i]);
printf("\n");
return 0;
}
这里有一些非常优秀的博客也可以进行参考理解