当前位置: 首页 > 编程日记 > 正文

哈夫曼编译码器

前言:又到了学校一年一度的数据结构课设的日子,经不住学弟学妹热心地“询问”我数据结构课设的内容,我就在这里把我之前数据结构课设做的东西总结一下

哈夫曼编译码器

我课设选择的题目是哈夫曼编译码器,类似于我们平时用的解压缩软件,可以把大文件压缩成一个较小的文件。

设计目的

数据结构课程设计的主要目的是使学生通过系统分析、系统设计、编程调试、写实验报告等环节,进一步掌握应用系统设计的方法和步骤,灵活运用并深刻理解典型数据结构在软件开发中的应用,进一步提高分析问题和解决问题的能力,提高程序设计水平。

设计内容

哈夫曼编译码器
利用哈夫曼编码进行信息通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本,编写代码实现一个哈夫曼的编/译码器,要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码(复原)。
具体功能包括:

  1. 建立哈夫曼树:读入文件(xxx.souce),统计文件中字符出现的频度,并以这些字符的频度作为权值,建立哈夫曼树。
  2. 编码:利用已建立好的哈夫曼树,获得各个字符的哈夫曼编码,并对正文进行编码,然后输出编码结果,并存入文件(xxx.code)中。
  3. 译码:利用已建立好的哈夫曼树将文件( xxx.code)中的代码进行译码,并输出译码结果,并存入文件( xxx.decode)中。
  4. 利用位操作,实现文件的压缩与解压。(选作)

概要设计

压缩解压缩界面:
这是一个使用JavaFx编写的一个简单的图形界面,可以进行压缩和解压缩文件的选择,选择完即可对被选择的文件进行压缩或解压缩。

压缩功能

压缩功能是按照文件里面的各个元素按照权值(即元素出现的次数)形成哈夫曼树,再通过遍历形成的哈夫曼树形成哈夫曼编码,再对形成的哈夫曼编码进行按位压缩(即每8位形成一个字节),最后将按位压缩后的编码、哈夫曼树的元素以及这些元素对应的权值和该文件的名字格式写入压缩文件里面方便进行下一次解压缩操作。

解压缩功能

解压缩功能流程跟压缩的流程差不多,同样是读取文件,将压缩时存进文件里面的信息读取出来,首先根据读取到字节数组重新恢复哈夫曼编码,然后根据读取到的哈夫曼树的信息重新创建哈夫曼树,再遍历哈夫曼树重新形成哈夫曼编码集合,遍历哈夫曼编码重新形成字符数组,根据字符数组恢复原来的字节数组,最后使用得出的字节数组恢复原来的文件即可得到压缩前的文件。

功能模块图

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

各个模块详细的功能描述

压缩

待压缩文件读取:
读取选取的待压缩文件,并将里面的数据用字节数组转化为字符数组,最后返回该字符数组;
统计字符出现的次数:
统计文件读取出来字符数组里面各个字符出现的次数,将他们储存在Map集合里面;
创建哈夫曼树:
根据统计出来字符次数的集合来创建哈夫曼树;
遍历哈夫曼树:
创建完哈夫曼树之后将哈夫曼树遍历得到各个叶子节点的编码,并将这些编码储存到集合里面;
形成哈夫曼编码:
根据叶子节点的编码遍历字符数组得到哈夫曼编码,并返回编码字符串;
对哈夫曼编码压缩:
将哈夫曼编码字符串按位压缩成字节数组,并返回该字节数组;
将压缩完的哈夫曼编码存进文件:
将哈夫曼编码压缩完后返回的字节数组给储存进压缩文件里面;

解压缩

读取压缩文件:
读取待解压缩的文件,将哈夫曼树、哈夫曼编码字节数组、原文件名和格式返回;
恢复哈夫曼编码:
对读取到的哈夫曼编码的字节数组重新转为字符串,即将字节重新恢复成二进制字符串;
重新创建哈夫曼树:
根据读取到的哈夫曼树的叶子和权值信息重新创建哈夫曼树;
遍历哈夫曼树:
遍历哈夫曼树得到叶子的编码,然后根据哈夫曼编码字符串遍历,获得原来的字符数组,再将支付数组转为字节数组返回;
恢复原文件数据:
根据返回的字节数组和之前读取到的原文件的格式和名字,重新创建文件,并往里面写入信息来恢复原来的文件信息。

详细设计

功能函数的调用关系

在这里插入图片描述

各功能函数的数据流程图

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

重点设计及编码

将哈夫曼编码按位进行压缩的操作

 public static byte[] codeZip(String code){int len;if (code.length()%8==0){len = code.length()/8;}else{len = code.length()/8+1;}byte[]bytes = new byte[len];int index = 0;for (int i = 0;i < code.length();i += 8){String strByte;if (i+8>code.length()){strByte = code.substring(i);}else{strByte = code.substring(i,i+8);}//Integer.parseInt(strByte, 2)方法的作用是输出二进制strByte数变成十进制后的数//如:1010变为十进制后为10bytes[index] = (byte) Integer.parseInt(strByte,2);index++;}return bytes;
}

对哈夫曼编码重新恢复成字符数组的操作

public static char[] enCode(String code, Map<String,Character> map){List<Character> list = new ArrayList<>();for(int i = 0; i < code.length(); ) {int count = 1;boolean flag = true;Character b = null;String key = null;while(flag) {if (i+count<=code.length()){key = code.substring(i, i + count);}else{//如果到了结尾而且key还找不到匹配的值,就对key进行补零的操作key="0"+key;System.out.println(key);}b = map.get(key);if (b == null) {++count;} else {flag = false;}}list.add(b);i+=count;}char[]chars = new char[list.size()];for (int i=0;i<chars.length;i++){chars[i] = list.get(i);}return chars;}

测试数据及运行结果

正常测试数据和运行结果

解压缩txt文件

压缩前:

在这里插入图片描述

压缩完:

在这里插入图片描述
解压后:
在这里插入图片描述

控制台输出:

在这里插入图片描述

输出哈夫曼树节点信息、哈夫曼编码、哈夫曼编码长度、压缩比率等

解压缩mp4文件

解压前:

在这里插入图片描述

压缩后:

在这里插入图片描述

解压后:

在这里插入图片描述

控制台输出:

在这里插入图片描述

输出哈夫曼树节点信息、哈夫曼编码、哈夫曼编码长度、压缩比率等

异常测试数据及运行结果

压缩大文件

在这里插入图片描述

报错:

在这里插入图片描述

这是因为 Java 虚拟机的堆内存不足导致的报错,这个我得吐槽一下,当初做的匆忙,直接用 String 类型存的编码,导致压缩不了太大的文件…

压缩空文件

在这里插入图片描述

报错:

在这里插入图片描述

这是因为没有加入文件判空的判断(因为当时想着不会有人压缩一个空文件…吧,好吧,还真有人会压缩空文件)

调试情况,设计技巧及体会

改进方案

现在的哈夫曼编译码器基本实现了实验要求的功能,但是还是有一定的不足和改进的空间的,如下:

  1. 加上对文件判空的判断,以免当压缩空文件的时候编译器报错;
  2. 对压缩大文件时 Java 虚拟机内存溢出的解决方法,可以将使用IO流来解决,可以设置一个限值,当读入了 10M 的数据时,一边读取文件一边进行文件数据的操作,对文件数据操作完之后再将操作完的数据输出到压缩文件里面,读取完这10M再继续依照上面的流程进行读取操作,即分片段读写。这样可以大大减少对虚拟机内存的占用,加快虚拟机处理数据的速度。
  3. JavaFx 编写的界面的美化度还有待提高,可以加上进度条,表示压缩进行到哪一步了,这样可以给人更直观的感受你压缩与解压缩的过程,毕竟不是人人都能看到软件运行时控制台的输出信息的。

体会

这次课设令我收获颇多,将课上学习到的哈夫曼树的知识应用到实际上并做出了一个程序,知道了如何使用代码创建哈夫曼树,创建完后如何将哈夫曼树转为哈夫曼编码,课设之前以为转化为哈夫曼编码再存到文件里面就能实现文件的压缩了,但在写程序的时候才发现这样反而使得文件变得更大了,想要达到压缩的要求,还需要对获得的哈夫曼编码进行按位压缩,按位压缩即将”01”哈夫曼编码按照8位重新压缩成一个字节,理论上数据重复度非常高的时候能使内存减少7到8倍,这样才能使文件达到压缩的效果,而且为了能解压缩,还要往文件里面记录哈夫曼树的信息来恢复哈夫曼树。

参考文献

参考文献多是学校教材…虽然我好像多数是直接上百度查的…

[1] 王曙燕.数据结构与算法. 北京:高等教育出版社. 2019
[2] 王曙燕.数据结构与算法. 北京:人民邮电出版社. 2013
[3] 耿国华.数据结构C语言描述. 北京:高等教育出版社. 2011
[4] 严蔚敏.数据结构. 北京:清华大学出版社. 2012
[5] 王曙燕.C语言程序设计教程. 北京:人民邮电出版社. 2014

最后

项目地址如下:
Github 地址:https://github.com/guanchanglong/HuffmanEncoder/tree/master
麻烦各位可否在看代码的时候顺手给一颗星 ^ _ ^,举手之劳感激不尽。

PS:也可以到我的个人博客查看更多内容
个人博客地址:小关同学的博客

相关文章:

Codeforces 629D Babaei and Birthday Cake(树状数组优化dp)

题意&#xff1a; 线段树做法 分析&#xff1a; 因为每次都是在当前位置的前缀区间查询最大值&#xff0c;所以可以直接用树状数组优化。比线段树快了12ms~ 代码&#xff1a; #include<cstdio> #include<cmath> #include<iostream> #include<algorithm>…

2022-2028年中国钢筘行业市场研究及前瞻分析报告

【报告类型】产业研究 【报告价格】4500起 【出版时间】即时更新&#xff08;交付时间约3个工作日&#xff09; 【发布机构】智研瞻产业研究院 【报告格式】PDF版 本报告介绍了中国钢筘行业市场行业相关概述、中国钢筘行业市场行业运行环境、分析了中国钢筘行业市场行业的…

控制台绘制正切曲线

前面介绍了&#xff1a;控制台绘制正弦/余弦曲线 , 控制台绘制正弦曲线和余弦曲线同时显示 下面来看看正切曲线吧&#xff0c;其实也都差不多…… #include <stdio.h> #include <math.h>int main() {double y;int x,k;for(y10;y>-10;y--){katan(y)*7;if(k>0)…

PX4多机ros仿真报错

出现报错&#xff1a; 缺少配置文件&#xff0c;需要添加路径到文件中&#xff1b; 在根目录下打开终端输入&#xff1a; 出现下面一个界面&#xff1a;&#xff08;蓝色是我添加的&#xff09; 保存退出&#xff1b; 重新进行刚开始的操作&#xff1a; 使用默认的.launc…

Unity创建2D动作RPG游戏 Create Action 2D RPG Game in Unity

在Unity中创建动作2D RPG游戏 大小解压后&#xff1a;5.69G 时长10h 包含 Udemy Game Asset.unitypackage 源文件 1280X720 MP4 语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09; 你会学到什么 学习基础来提升C#&#xff0c; 为远程和特殊攻击…

Nginx学习4:负载均衡实例

Nginx配置实例-负载均衡 目标 在浏览器地址栏输入地址 http://192.168.126.131:8080/edu/a.html&#xff0c;负载均衡效果&#xff0c;平均分配到 8080 和 8081 端口中 准备工作 &#xff08;1&#xff09;准备两台 tomcat 服务器&#xff0c;一台 8080&#xff0c;一台 80…

2016030204 - git和github结合

1.下载和安装git客户端 参考&#xff1a;http://www.cnblogs.com/zhtzyh2012/p/5232291.html 2.github上创建项目 参考&#xff1a;http://www.cnblogs.com/zhtzyh2012/p/5233495.html 3.密钥相关信息设置 参考&#xff1a;http://www.cnblogs.com/zhtzyh2012/p/5233630.html 4…

2022-2028年中国钢化玻璃行业市场研究及前瞻分析报告

【报告类型】产业研究 【报告价格】4500起 【出版时间】即时更新&#xff08;交付时间约3个工作日&#xff09; 【发布机构】智研瞻产业研究院 【报告格式】PDF版 本报告介绍了中国钢化玻璃行业市场行业相关概述、中国钢化玻璃行业市场行业运行环境、分析了中国钢化玻璃行…

nginx如何解决超长请求串

nginx是一个强大的http服务器&#xff0c;但是在使用过程中发现&#xff0c;当遇到超长的post请求或者get请求时&#xff0c;nginx会返回413、400、414等状态码&#xff0c;这是因为请求串长度超过了nginx默认的缓存大小或者请求串大小&#xff0c;那么我们需要怎么样来解决这些…

ubuntu安装qwt出现错误时"mkdir: 无法创建目录“/usr/local/qwt-6.1.3“: 权限不够"

报错&#xff1a; 在root用户下执行操作&#xff0c;参考链接安装qwt

Unity 2021人工智能导论 Introduction to Artificial Intelligence in Unity 2021

学习视频游戏开发中最常用的人工智能技术的基础知识。 你会学到什么 了解如何使用有限状态机 学习行为树的基础知识 了解如何实现阿斯塔寻路算法 了解如何在游戏中实现传感器 了解如何创建GOAP系统 了解植绒的基本知识 流派:电子学习| MP4 |视频:h264&#xff0c;1280720 |音频…

HikariPool 连接池问题

前言&#xff1a;今天在一个项目运行的时候发现一个很奇怪的问题&#xff0c;当我有一段时间无操作之后再进行插入操作的话&#xff0c;就会出现HikariPool相关的报错&#xff0c;在此记录一下 问题 2022-02-20 13:14:04.178 WARN 4012 --- [nio-8888-exec-6] com.zaxxer.hik…

谈谈对web标准的理解

Web标准不是某一个标准&#xff0c;而是由一系列标准组合而成。网页主要由三部分组成&#xff1a;结构、表现和行为。对应的标准也分三方面&#xff1a;结构化标准语言主要包括XHTML和HTML以及XML&#xff0c;表现标准语言主要包括CSS&#xff0c;行为标准主要包括对象模型&…

2022-2028年中国二次供水设备行业研究及前瞻分析报告

【报告类型】产业研究 【报告价格】4500起 【出版时间】即时更新&#xff08;交付时间约3个工作日&#xff09; 【发布机构】智研瞻产业研究院 【报告格式】PDF版 本报告介绍了中国二次供水设备行业市场行业相关概述、中国二次供水设备行业市场行业运行环境、分析了中国二…

linux磁盘配额管理

linux-用户磁盘配额磁盘配额就是管理员可以为用户所能使用的磁盘空间进行配额限制&#xff0c;每一用户只能使用最大配额范围内的磁盘空间磁盘配额可以限制指定账户能够使用的磁盘空间,这样可以避免因某个用户的过度使用磁盘空间造成其他用户无法正常工作甚至影响系统运行。在服…

终端打不开(右键和快捷键)?因为phthon?

参考连接&#xff1a;https://www.cnblogs.com/dolphi/p/3622570.html 在总的环境变量中删除掉LC_ALL这一项&#xff0c;重新启动后即可恢复以及打开终端&#xff1b; 具体怎么操作&#xff1a;是师兄帮弄的&#xff0c;没看清楚怎么操作&#xff01;

Unity从头到尾无代码游戏制作学习教程

制作没有代码的游戏 Unity中的主视觉脚本&#xff01; 流派:电子学习| MP4 |视频:h264&#xff0c;1280720 |音频:AAC&#xff0c;48.0 KHz 语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09;|大小解压后:26.2 GB 含课程文件|时长:21小时 11分…

经常使用ARM汇编指令

一面学习&#xff0c;一面总结&#xff0c;一面记录。 以下是整理在网上找到的一些资料&#xff0c;简单整理记录一下&#xff0c;方便以后查阅。 ARM处理器的指令集能够分为跳转指令、数据处理指令、程序状态寄存器&#xff08;PSR&#xff09;处理指令、载入/存储指令、协处理…

解决 Could not autowire. No beans of ‘UserDao‘ type found 问题

前言&#xff1a;今天在完善项目的时候发现使用Autowired注入的Dao层依赖出现报错&#xff0c;但是不影响项目的运行&#xff0c;在此记录一下 问题 这个错误不影响项目运行&#xff0c;但是它看着很烦… 分析 Dao层代码&#xff1a; Mapper public interface UserDao {User…

2022-2028年中国二次供水产业发展动态及投资战略规划报告

【报告类型】产业研究 【报告价格】4500起 【出版时间】即时更新&#xff08;交付时间约3个工作日&#xff09; 【发布机构】智研瞻产业研究院 【报告格式】PDF版 本报告介绍了中国二次供水行业市场行业相关概述、中国二次供水行业市场行业运行环境、分析了中国二次供水行…

Tomcat安全

一、版本安全 升级当前的tomcat版本为最新稳定版本。故名思议&#xff0c;最新稳定版本就要兼顾最新和稳定这两个概念。一个稳定的版本&#xff0c;是需要时间沉淀的&#xff0c;而最新又是相对于稳定版而言的最新。因此我们一般会选择当前大版本中&#xff0c;最新版本往前推几…

Linux系统下给Qt应用程序配置图标(其余的应用程序也是可以实现添加图标的)

添加链接描述1.创建启动脚本 打开终端输入&#xff1a; touch run.sh在/home目录下找到run.sh文件&#xff0c;双击打开编辑&#xff1b; #&#xff01;/bin/bash cd /execute/home/xxx/ &#xff03;/home/xxx/是Release编译以后生成的应用程序的路径 ./Json2.创建d…

Unity完全学习教程-从初学者到C#中的RPG游戏开发

打造3款游戏&学习Unity实用方式&#xff01;从基础开始&#xff0c;以一个RPG游戏结束。使用Unity 2020和C# 你会学到: 通过创建酷游戏的实用方法 游戏开发的基础和核心概念 创建一个拥有大量功能的角色扮演游戏 代码背后的数学解释。 要求 最基本的C#或其他面向对象语言…

2345电脑管家_极限挑战:同时安装4大国产杀毒软件,我的电脑是最安全的?

还没到国庆假期&#xff0c;老毛桃就提前给自己放了假&#xff0c;闲着就作妖&#xff0c;这不&#xff1f;现在就忙着卸载。人固有一秃&#xff0c;或秃于科研&#xff0c;或秃于卸载&#xff01;说到作妖&#xff0c;是怎么一回事呢&#xff1f;此前不少网友私信让老毛桃挑战…

Sublime Text 3 及Package Control 安装(附上一个3103可用的Key)

一、Sublime Text 3 下载。 官方下载地址&#xff1a;http://www.sublimetext.com/ 二、Sublime Text 3 安装。 打开安装包&#xff0c;进行傻瓜式安装。 三、注册。 点击Help&#xff0c;选择Enter License&#xff0c;出现如下输入框。 输入注册码。 —– BEGIN LICENSE —–…

2022-2028年中国儿童医疗行业深度调研及投资前景预测报告

【报告类型】产业研究 【报告价格】4500起 【出版时间】即时更新&#xff08;交付时间约3个工作日&#xff09; 【发布机构】智研瞻产业研究院 【报告格式】PDF版 本报告介绍了中国儿童医疗行业市场行业相关概述、中国儿童医疗行业市场行业运行环境、分析了中国儿童医疗行…

使用Spring的@Autowired 实现DAO, Service, Controller三层的注入(转)

简述&#xff1a; 结合Spring和Hibernate进行开发 使用Autowired实现依赖注入&#xff0c; 实现一个学生注册的功能&#xff0c;做一个技术原型 从DAO(Repository) -> Service -> Controller 目录结构&#xff1a; 使用Maven做本地包管理&#xff0c; pom.xml [java]view…

Ubuntu安装QT后无法输入中文怎么办?

文件目录打开&#xff1a; 文件位置/Qt5.12.6/Tools/QtCreator/lib/Qt/plugins/platforminputcontexts 查看是否存在libfcitxplatforminputcontextplugin.so库文件&#xff08;第一次装肯定没有&#xff09;放进去以后重新启动QT即可输入中文该库下载位置&#xff1a; ununtu…

Unity空间射击游戏开发教程

描述 在本课程中&#xff0c;您将学习如何在unity中制作一款太空射击游戏。本课程使用全新的特性和编码实践&#xff0c;并且兼容所有较新版本的unity。 了解如何使用世界领先的免费游戏开发工具Unity创建太空射击游戏。有了我们的在线教程&#xff0c;你会惊讶于创建这样一个…

43.放苹果(递归练习)

放苹果 总时间限制: 1000ms 内存限制: 65536kB 描述 把M个同样的苹果放在N个同样的盘子里&#xff0c;允许有的盘子空着不放&#xff0c;问共有多少种不同的分法&#xff1f;&#xff08;用K表示&#xff09;5&#xff0c;1&#xff0c;1和1&#xff0c;5&#xff0c;1 是同…