永发信息网

输入五个字符并根据它出现的概率生成一颗哈夫曼数

答案:1  悬赏:0  手机版
解决时间 2021-07-18 15:28

1、在VC++平台编制程序,根据输入的字符(最多为五个字符)及其出现的概率能够生成一棵Huffman树。

2、输入的字符串,使用上面生成的Huffman树进行译码
最佳答案

VC2003平台, 成功编译运行,测试结果正确


测试数据字符数5


测试码文='a','e','r','t','d'


测试码文出现次数=8,4,6,3,1


测试电文1="01011101111100011";


测试电文2="0101011010";


#include "stdafx.h"


#include <stdio.h>
#include <string.h>
#define N 50 //叶子结点数/
#define M 2*N-1 //树中结点总数/


typedef struct
{
char data[5]; //结点值/
int weight; //权重/
int parent; //双亲结点/
int lchild; //左孩子结点/
int rchild; //右孩子结点/
} HTNode;


typedef struct
{
char cd[N]; //存放哈夫曼码/
int start;
} HCode;


void CreateHT(HTNode ht[],int n)
{
int i,k,lnode,rnode;
int min1,min2;
for (i=0;i<2*n-1;i++) //所有结点的相关域置初值-1/
ht[i].parent=ht[i].lchild=ht[i].rchild=-1;
for (i=n;i<2*n-1;i++) //构造哈夫曼树/
{
min1=min2=32767; //lnode和rnode为最小权重的两个结点位置/
lnode=rnode=-1;
for (k=0;k<=i-1;k++)
if (ht[k].parent==-1) //只在尚未构造二叉树的结点中查找/
{
if (ht[k].weight<min1)
{
min2=min1;rnode=lnode;
min1=ht[k].weight;lnode=k;
}
else if (ht[k].weight<min2)
{
min2=ht[k].weight;rnode=k;
}
}
ht[lnode].parent=i;ht[rnode].parent=i;
ht[i].weight=ht[lnode].weight+ht[rnode].weight;
ht[i].lchild=lnode;ht[i].rchild=rnode;
}
}


void CreateHCode(HTNode ht[],HCode hcd[],int n)
{
int i,f,c;
HCode hc;
for (i=0;i<n;i++) //根据哈夫曼树求哈夫曼编码/
{
hc.start=n;c=i;
f=ht[i].parent;
while (f!=-1) //循序直到树根结点/
{
if (ht[f].lchild==c) //处理左孩子结点/
hc.cd[hc.start--]='0';
else //处理右孩子结点/
hc.cd[hc.start--]='1';
c=f;f=ht[f].parent;
}
hc.start++; //start指向哈夫曼编码最开始字符/
hcd[i]=hc;
}
}


void DispHCode(HTNode ht[],HCode hcd[],int n)
{
int i,k;
int sum=0,m=0;
printf(" 输出哈夫曼编码:\n"); //输出哈夫曼编码/
for (i=0;i<n;i++)
{
int j=0;
printf(" %s:\t",ht[i].data);
for (k=hcd[i].start;k<=n;k++)
{
printf("%c",hcd[i].cd[k]);
j++;
}
m+=ht[i].weight;
sum+=ht[i].weight*j;
printf("\n");
}
printf("\n 平均长度=%g\n",1.0*sum/m);
}
int findsubstr(char* S, int cS, HCode hcd[],int n, int &pos)
{
int i,k, j;
if (pos > cS) return -1;
for (i=0;i<n;i++)
{
j = pos;
for (k=hcd[i].start;k<=n;k++)
{
if (S[j] == hcd[i].cd[k])
j++;
else
break;
}
if (k > n)
{
pos = j;
return i;
}
}
return -1;
}


bool Recode(char* S, int cS, HTNode ht[],HCode hcd[],int n){
char strresult[80]={'\0'};
int pos = 0;
while (pos < cS)
{
int result = findsubstr(S, cS, hcd, n, pos);
if (result != -1)
{
strcat(strresult, ht[result].data);
}
else
return false;
}
printf("译码结果为:%s\n\n", strresult);
return true;
}
void main()
{
int i, n;
char str[6][2];
int fnum[6];
memset(str,'\0',12*sizeof(char));
printf("输入字符个数\n");
scanf("%d", &n);
getchar();


printf("开始录入字符\n");
for (int i = 0;i<n;i++)
{
scanf("%c",str[i]);
getchar();
}


printf("开始录入字符出现次数\n");


for (int i = 0;i<n;i++)
{
scanf("%d",&fnum[i]);
getchar();
}


HTNode ht[M];
HCode hcd[N];
for (i=0; i<n; i++)
{
strcpy(ht[i].data, str[i]);
ht[i].weight=fnum[i];
}
printf("\n");
CreateHT(ht,n);
CreateHCode(ht,hcd,n);
DispHCode(ht,hcd,n);
printf("\n");


char* strtest1="01011101111100011";
printf("破译原文是:%s\n", strtest1);
int clength = strlen(strtest1);
if (!Recode(strtest1, clength, ht, hcd, n))
printf("译密失败\n");


char* strtest2="0101011010";
printf("破译原文是:%s\n", strtest2);
clength = strlen(strtest2);
if (!Recode(strtest2, clength, ht, hcd, n))
printf("译密失败\n");


system("pause");
}

我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
老师给小学毕业生寄语,幼儿园毕业就要步入小
手提电脑价格起伏?
如何下载视频在空间日志
黄英的个人资料
爱一个人是陪着他,还是让他找真正爱的人自己
什么操作系统好点
随便问问,考考你。
请问摆地摊卖什么能赚些零用钱
纪无常是那本小说中的人物
吃葛根丰胸多久能见效,葛根粉如何吃对丰胸效
最伤感的内地音乐是什么
我生了小孩之后就特别胖。有产后减肥的特效药
itudou视频装换出来的在哪个文件夹里??
成吉思汗怎么修改玩家资料啊?谢谢
DNF账号被封申诉多久可以解封?
推荐资讯
如果我和她相爱而不能在一起我该放弃吗
精进砥砺是什么意思,思圆行方 砥砺精进 10分
“我的电脑”图标没了?怎么出来 搞了一个快
有效的丰胸产品。。
有谁知道李雅微的血型??、和喜欢的人???
关于读书的古诗句
贵州省中级教师资格证考试模拟
OPPO A105K手机能下载手机电视吗?或能下载什
黄瓜属于瓜果还是蔬菜?
中文的各种连接词用英语怎样表示
电视剧雪在烧
WOW部落SM水图腾任务多少级接得到
正方形一边上任一点到这个正方形两条对角线的
阴历怎么看 ?