一、 实验目的

熟练掌握哈夫曼树的建立和哈夫曼编码的算法实现。

二、 实验内容

根据哈夫曼编码的原理,编写一个程序,在用户输入结点权值的基础上求赫夫曼编码,并能把给定的编码进行译码。

三、 实验要求

(1)初始化:从键盘输入一字符串(或读入一文件),统计出现的字符和每个字符出现的频率,将字符出现的频率作为结点的权值,建立哈夫曼树。对各个字符进行哈夫曼编码,最后打印输出字符及每个字符对应的哈夫曼编码。

(2)编码:利用已建好的哈夫曼树对“输入串”进行哈夫曼编码,最后打印输入串对应的哈夫曼编码(写入文件)。

(3)计算压缩比(选作)

(4)译码:利用已建好的哈夫曼树对给定的一串代码进行译码,并打印输出得到的字符串。(选作)

测试数据:对字符串{casbcatbsatbat}进行编码;对电文“1101000”译码。字符集D={   ?},出现频率为w={?}

 #include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>
#include <math.h>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <sstream>
const int INF=0x3f3f3f3f;
typedef long long LL;
const int mod=1e9+;
const int maxn=1e4+;
using namespace std; struct node
{
int val;//权值
int lc;//左孩子
int rc;//右孩子
int parent;//双亲
char c;//节点字符
int flag;//标志
}Huffman_Tree[*]; int num[]={};//每种字符的个数
char Huffman_code[][];//每种字符对应的编码
char str[maxn];//原字符串
int cnt;//Huffman树节点个数计数器 void Init()//初始化
{
printf("请输入一串字符串(该字符串只能为小写字母):\n");
gets(str);
for(int i=;str[i];i++)
{
num[str[i]-'a']++;
}
int sum=;
for(int i=;i<;i++)
{
if(num[i])//初始化
{
sum++;
Huffman_Tree[++cnt].c=i+'a';
Huffman_Tree[cnt].val=num[i];
Huffman_Tree[cnt].lc=;
Huffman_Tree[cnt].rc=;
Huffman_Tree[cnt].parent=;
Huffman_Tree[cnt].flag=;
}
}
for(int k=;k<sum-;k++)//建树
{
int MIN1=INF;
int MIN2=INF;
int Index1,Index2;
for(int i=;i<=cnt;i++)
{
if(Huffman_Tree[i].flag==)
{
if(Huffman_Tree[i].val<MIN1)
{
MIN2=MIN1;
Index2=Index1;
MIN1=Huffman_Tree[i].val;
Index1=i;
}
else if(Huffman_Tree[i].val<MIN2)
{
MIN2=Huffman_Tree[i].val;
Index2=i;
}
}
}
Huffman_Tree[Index1].flag=;
Huffman_Tree[Index2].flag=;
int t=MIN1+MIN2;
Huffman_Tree[++cnt].val=t;
Huffman_Tree[cnt].c='*';
Huffman_Tree[cnt].lc=Index1;
Huffman_Tree[cnt].rc=Index2;
Huffman_Tree[cnt].parent=;
Huffman_Tree[cnt].flag=;
Huffman_Tree[Index1].parent=cnt;
Huffman_Tree[Index2].parent=cnt;
}
for(int i=;i<;i++)//求Huffman编码
{
if(num[i])
{
char tem[];
int len=;
int p;
for(int j=;j<=cnt;j++)
{
if(Huffman_Tree[j].c==i+'a')
{
p=j;
break;
}
}
while(Huffman_Tree[p].parent)
{
if(Huffman_Tree[Huffman_Tree[p].parent].lc==p)
tem[len++]='';
else
tem[len++]='';
p=Huffman_Tree[p].parent;
}
tem[len]='\0';
int ccnt=;
for(int j=len-;j>=;j--)
{
Huffman_code[i][ccnt++]=tem[j];
}
Huffman_code[i][ccnt]='\0';
// for(int j=0;j<len/2;j++)
// {
// char t=tem[j];
// tem[j]=tem[len-1-j];
// tem[len-1-j]=t;
// }
// NUM[i]=tem;
// puts(NUM[i]);
}
}
printf("每个字母对应的Huffman编码为:\n");
for(int i=;i<;i++)
{
if(num[i])
{
printf("%c:",i+'a');
puts(Huffman_code[i]);
}
}
} void Print_out()//编码
{
printf("输入串对应的哈夫曼编码为:\n");
for(int i=;str[i];i++)//根据字符匹配编码
{
printf("%s",Huffman_code[str[i]-'a']);
}
printf("\n");
} void Solve1()//计算压缩比
{
int sum=;//字符种类个数
for(int i=;i<;i++)
{
if(num[i])
sum++;
}
double a=;//平均码长
int b;//等长码
if(sum==)
b=;
else b=(int)log2(sum-)+;
double ans;
for(int i=;i<;i++)
{
if(num[i])
{
a+=(num[i]*1.0/strlen(str))*strlen(Huffman_code[i]);
}
}
ans=a/b*1.0;
printf("该字符串压缩比为:\n");
printf("%.2lf%%\n",ans*);
} void Solve2()//译码
{
char tem[maxn];
// char ans[maxn];
// int len=0;
printf("请输入要进行译码的0-1串:\n");
scanf("%s",tem);
// int i,j,k;
// for(i=0;tem[i];i++)
// {
// for(k=0;k<26;k++)
// {
// if(num[k])
// {
// for(j=0;j<strlen(Huffman_code[k]);)
// {
// if(tem[i]==Huffman_code[k][j])
// {
// i++;
// j++;
// }
// else
// {
// i-=j;
// j=0;
// break;
// }
// }
// if(j==strlen(Huffman_code[k]))
// {
// i--;
// ans[len++]=k+'a';
// break;
// }
// }
// }
// }
// ans[len]='\0';
// printf("该0-1串译文为:\n");
// puts(ans);
int rt;//Huffman树根
for(int i=;i<=cnt;i++)//找到根
{
if(Huffman_Tree[i].parent==)
{
rt=i;
break;
}
}
for(int i=;tem[i];i++)//类似于字典树匹配
{
for(int p=rt;;i++)
{
if(tem[i]=='')
p=Huffman_Tree[p].lc;
else
p=Huffman_Tree[p].rc;
if(Huffman_Tree[p].c!='*')
{
printf("%c",Huffman_Tree[p].c);
break;
}
}
}
printf("\n");
} int main()
{
Init();
printf("--------------------------------\n");
Print_out();
printf("--------------------------------\n");
Solve1();
printf("--------------------------------\n");
Solve2();
printf("--------------------------------\n");
return ;
}

Huffman编码实验的更多相关文章

  1. Jcompress: 一款基于huffman编码和最小堆的压缩、解压缩小程序

    前言 最近基于huffman编码和最小堆排序算法实现了一个压缩.解压缩的小程序.其源代码已经上传到github上面: Jcompress下载地址 .在本人的github上面有一个叫Utility的re ...

  2. [老文章搬家] 关于 Huffman 编码

    按:去年接手一个项目,涉及到一个一个叫做Mxpeg的非主流视频编码格式,编解码器是厂商以源代码形式提供的,但是可能代码写的不算健壮,以至于我们tcp直连设备很正常,但是经过一个UDP数据分发服务器之后 ...

  3. Huffman编码

    #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <cstdio> #include <cstri ...

  4. 【数据压缩】Huffman编码

    1. 压缩编码概述 数据压缩在日常生活极为常见,平常所用到jpg.mp3均采用数据压缩(采用Huffman编码)以减少占用空间.编码\(C\)是指从字符空间\(A\)到码字表\(X\)的映射.数据压缩 ...

  5. 优先队列求解Huffman编码 c++

    优先队列小析      优先队列的模板: template <class T, class Container = vector<T>,class Compare = less< ...

  6. Huffman编码实现电文的转码与译码

    //first thing:thanks to my teacher---chenrong      Dalian Maritime university /* 构造Huffman Tree思路: ( ...

  7. huffman 编码

    huffman压缩是一种压缩算法,其中经典的部分就是根据字符出现的频率建立huffman树,然后根据huffman树的构建结果标示每个字符.huffman编码也称为前缀编码,就是每个字符的表示形式不是 ...

  8. 基于二叉树和数组实现限制长度的最优Huffman编码

    具体介绍详见上篇博客:基于二叉树和双向链表实现限制长度的最优Huffman编码 基于数组和基于链表的实现方式在效率上有明显区别: 编码256个符号,符号权重为1...256,限制长度为16,循环编码1 ...

  9. uvalive 2088 - Entropy(huffman编码)

    题目连接:2088 - Entropy 题目大意:给出一个字符串, 包括A~Z和_, 现在要根据字符出现的频率为他们进行编码,要求编码后字节最小, 然后输出字符均为8字节表示时的总字节数, 以及最小的 ...

随机推荐

  1. windows Driver 查询指定键值

    NTSTATUS status; HANDLE hKey = NULL; OBJECT_ATTRIBUTES oa; UNICODE_STRING strPath = RTL_CONSTANT_STR ...

  2. Pycharm2020最新激活码|永久激活(附最新激活码和插件)

    最近很多人的Pycharm激活时间又过期了,后台很多人索要激活码,我就再把激活的方法汇和工具再梳理一次给大家. 最主要有两种激活方式(两种方式需要的激活码不同): 一.激活码激活: 一般一年多需要激活 ...

  3. 爬虫(十八):Scrapy框架(五) Scrapy通用爬虫

    1. Scrapy通用爬虫 通过Scrapy,我们可以轻松地完成一个站点爬虫的编写.但如果抓取的站点量非常大,比如爬取各大媒体的新闻信息,多个Spider则可能包含很多重复代码. 如果我们将各个站点的 ...

  4. Linux - 安装 dotnet core 环境

    Linux -  安装 dotnet core 环境 系统环境:CentOS7 官方安装指导 https://www.microsoft.com/net/learn/get-started/linux ...

  5. Linux|Zookeeper--CentOS7开机启动Zookeeper

    参考 https://www.cnblogs.com/zhangmingcheng/p/7455278.html 在 /etc/rc.d/init.d 下创建zookeeper脚本 #!/bin/ba ...

  6. JFrame的面板结构和JPanel的使用

    JFrame图解结构 有一窗口框架实例:JFrame win = new JFrame("窗口");在new JFrame()时,构建了JFrame实例对象,在实例中的Layere ...

  7. django_filter的values / values_list

    from django.db import models class Blog(models.Model): name = models.CharField(max_length=100) tagli ...

  8. WOJ 1543 Array

    还是聪哥给我讲的思路才知道的,起初我利用两两互质去求发现有问题,互质只是必要条件而非充分条件,后来还是用的标准思路 即其实最终只要保留最大的素数的幂即可,其他包含该素数幂但指数低的都不用了,这样就能保 ...

  9. 程序中出现list assignment index out of range的解决方法

    class stack: def __init__(self): self.num = 0 self.elem=[] def isEmoty(self): if self.num == 0: prin ...

  10. DevOps专题 | 大型企业级监控系统设计

    10月30日,全球权威数据调研机构IDC正式发布<IDCMarketScape: 中国DevOps云市场2019,厂商评估>报告.京东云凭借丰富的场景和实践能力,以及高质量的服务交付和平台 ...