Huffman 压缩和解压缩java实现
附上完整的代码
http://download.csdn.net/download/u010485034/7847447
Huffman编码原理这里就不说了,是。这里来讲讲利用Huffman编码来进行压缩和解压缩的详细实现吧。
本project使用java实现。
编码
1. 流程图
2. 数据结构
CharacterWeight:记录字符值,以及其在待压缩文件里的权重。
Class{
char c; //字符值
int weight; //在文件里权重
String code; //其相应huffman编码
}
HuffmanNode:huffman树中的节点信息。
Class{
Int parent; //父节点
Int lChild; //左儿子
Int rChild; //右儿子
Int weight; //权重
}
3. 程序关键点
3.1 Huffman树的构建
Huffman树的变量:ArrayList<HuffmanNode> list。
创建流程图:
for(int i=0;i<list.size()-1;i++){
//w1 : the first min weight w2: the second min weight
//i1 : the first min weight index, i2: the second min weight index
int w1 = MAX_VALUE, w2=MAX_VALUE;
int i1 = 0, i2 = 0;
// find the two node with the minimum weight
for(int j=0;j<tree.size();j++){
HuffmanNode node = tree.get(j);
if(node.getWeight()< w1 && node.getParent()==-1){
w2 = w1;
w1 = node.getWeight();
i2 = i1;
i1 = j;
}
else if(node.getWeight()<w2 && node.getParent()==-1){
w2 = node.getWeight();
i2 = j;
}
}
//set the two node to be the children of a new node, and add the new node to the tree
HuffmanNode pNode = new HuffmanNode(w1+w2);
pNode.setlChild(i1);
pNode.setrChild(i2);
tree.add(pNode);
tree.get(i1).setParent(tree.indexOf(pNode));
tree.get(i2).setParent(tree.indexOf(pNode));}
3.2 依据Huffman 树获得Huffman编码
从叶子节点開始网上遍历Huffman树。直到到达根节点。依据当前节点为其父节点的左儿子还是右儿子确定这一位值是0还是1。
最后将依次获得的0,1字符串反转获得Huffman编码。
代码:
for(int i=0;i<list.size();i++){
HuffmanNode node = tree.get(i);
HuffmanNode pNode = tree.get(node.getParent());
String code ="";
while(true){
if(pNode.getlChild()==tree.indexOf(node)){
code = "0"+code;
}
else if(pNode.getrChild() == tree.indexOf(node)){
code = "1"+code;
}
else {
System.out.println("Tree Node Error!!!");
return null;
}
node=pNode;
if(node.getParent()!=-1)
pNode=tree.get(node.getParent());
else
break;
}
list.get(i).setCode(new String(code));
}
3.3 文件头设计
字符总数 |
Int 四个字节 |
字符种类数 |
Short 两个字节 |
叶子节点 |
char字符 short 父节点 3个字节 |
非叶子节点 |
Short 左儿子 short 右儿子 short父节点 6字节 |
文件头长度(单位: byte)
l= 9n
当中n 为字符种类数。
3.4文件内容的编码和写入
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMDQ4NTAzNA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
while((temp=reader.read())!=-1){ //!= EOF
// get the code from the code table
String code = codeTable.get((char)temp);
c++;
if(c>=count/96){
System.out.print("=");
c=0;
}
try{
StringBuilder codeString = new StringBuilder(code);
outputStringBuffer.append(codeString);
while(outputStringBuffer.length()>8){
out.write(Short.parseShort(outputStringBuffer.substring(0, 8),2));
outputStringBuffer.delete(0, 8);
}
} catch(Exception e){
e.printStackTrace();
} }
解码
1. 流程图
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMDQ4NTAzNA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
2. 数据结构
HuffmanNode:huffman树中的节点信息。
Class{ Int parent; //父节点 Int lChild; //左儿子 Int rChild; //右儿子 Int weight; //权重 Char c; //相应的字符值 |
3. 程序关键点
3.1 重建Huffman树。在文件头中存放的原本就是Huffman树的节点信息,所以重建Huffman树是比較简单的。
代码:
in = new DataInputStream(new FileInputStream(file));
count = in.readInt();
charNum = in.readShort();
nodeNum = 2*charNum -1;
//rebuild the huffman tree
for(int i=0;i<charNum;i++){
HuffmanNode node = new HuffmanNode((char)in.readByte());
int parent = in.readShort();
node.setParent(parent);
tree.add(node);
} for(int i=charNum;i<nodeNum;i++){
HuffmanNode node = new HuffmanNode(' ');
int l = in.readShort();
int r = in.readShort();
int p = in.readShort();
node.setlChild(l);
node.setrChild(r);
node.setParent(p);
tree.add(node);
}
3.2 解码
解码流程图
while(true){
while(buff.length()<32){
temp = in.readInt();
String codeString = Integer.toBinaryString(temp);
while(codeString.length()<32){
codeString='0'+codeString;
}
buff.append(codeString);
}
node = tree.get(tree.size()-1);
dep = 0;
while(!(node.getlChild()==-1&&node.getrChild()==-1)){
if(dep>=buff.length()){
System.out.println( "Buff overflow");
}
if(buff.charAt(dep)=='0'){
node = tree.get(node.getlChild());
}
else if(buff.charAt(dep)=='1'){
node = tree.get(node.getrChild());
}
else{
System.out.println("Coding error");
}
dep++;
} char c = node.getCH();
num++;
if(num>=n/99){
System.out.print("=");
num=0;
}
count++;
if(count>=n){
break;
}
charBuff+=c;
if(charBuff.length()>256){
writer.write(charBuff);
charBuff="";
}
buff.delete(0, dep); } } catch(EOFException e){
//just do nothing
}
catch(Exception e){
e.printStackTrace();
} finally{
//there may be data released in the buff and charbuff, so we need to process them
while(buff.length()>0){
node = tree.get(tree.size()-1);
dep = 0;
while(!(node.getlChild()==-1&&node.getrChild()==-1)){
if(dep>=buff.length()){
break;
}
if(buff.charAt(dep)=='0'){
node = tree.get(node.getlChild());
}
else if(buff.charAt(dep)=='1'){
node = tree.get(node.getrChild());
}
else{
System.out.println("Coding error");
//return;
}
dep++;
}
char c = node.getCH();
num++;
if(num>=n/99){
System.out.print("=");
num=0;
}
count++;
if(count>=n){
break;
}
charBuff+=c;
if(charBuff.length()>256){
try {
writer.write(charBuff);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
charBuff="";
}
buff.delete(0, dep);
} try {
writer.write(charBuff);
writer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try{
writer.close();
} catch(IOException e){
throw e;
}
完成project没有公布,稍后更新。
版权声明:本文博客原创文章,博客,未经同意,不得转载。
Huffman 压缩和解压缩java实现的更多相关文章
- [Java 基础] 使用java.util.zip包压缩和解压缩文件
reference : http://www.open-open.com/lib/view/open1381641653833.html Java API中的import java.util.zip ...
- Java 的zip压缩和解压缩
Java 的zip压缩和解压缩 好久没有来这写东西了,今天中秋节,有个东西想拿出来分享,一来是工作中遇到的问题,一来是和csdn问候一下,下面就分享一个Java中的zip压缩技术,代码实现比较简单,代 ...
- Java用ZIP格式压缩和解压缩文件
转载:java jdk实例宝典 感觉讲的非常好就转载在这保存! java.util.zip包实现了Zip格式相关的类库,使用格式zip格式压缩和解压缩文件的时候,须要导入该包. 使用zipoutput ...
- java工具类——java将一串数据按照gzip方式压缩和解压缩
我要整理在工作中用到的工具类分享出来,也方便自己以后查阅使用,这些工具类都是我自己实际工作中使用的 import java.io.ByteArrayInputStream; import java.i ...
- java采用zip方式实现String的压缩和解压缩CompressStringUtil类
CompressStringUtil类:不多说,直接贴代码: /** * 压缩 * * @param paramString * @return */ public static final byte ...
- Java对zip格式压缩和解压缩
Java对zip格式压缩和解压缩 通过使用java的相关类可以实现对文件或文件夹的压缩,以及对压缩文件的解压. 1.1 ZIP和GZIP的区别 gzip是一种文件压缩工具(或该压缩工具产生的压缩文件格 ...
- Java基础--压缩和解压缩gz包
gz是Linux和OSX中常见的压缩文件格式,下面是用java压缩和解压缩gz包的例子 public class GZIPcompress { public static void FileCompr ...
- Java ZIP压缩和解压缩文件(解决中文文件名乱码问题)
Java ZIP压缩和解压缩文件(解决中文文件名乱码问题) 学习了:http://www.tuicool.com/articles/V7BBvy 引用原文: JDK中自带的ZipOutputStrea ...
- Java压缩和解压缩文件工具
Java压缩和解压缩文件工具 学习了: https://www.oschina.net/code/snippet_1021818_48130 http://blog.csdn.net/gaowen_h ...
随机推荐
- a web-based music player(GO + html5)
github 住址:https://github.com/codercheng/music-player 后台是用GO (windows/ linux 都能够),前端是HTML5 推荐用chrome浏 ...
- ubuntu经常使用的命令摘要
1.df命令 # df -ha 显示所有文件和分区的使用 # df -h /dev/sda1 显示sda1磁盘使用率 # df -T 显示文件系统名称属于每个分区.区的格式类型(比方ext3) 注:h ...
- 7 Ways to earn money on programming(转)
英文原文:7 Ways to earn money on programming 几个星期前,当我收到一个自称 Someone712 的人发给我的一条消息时,我决定要写一篇如何用编程赚钱的博客文章.S ...
- sql语句like的使用方法
在SQL结构化查询语言中,LIKE语句有着至关关键的数据. LIKE语句的语法格式是:select * from 表名 where 字段名 like 相应值(子串),它主要是针对字符型字段的,它的作用 ...
- 《R实战》读书笔记三
第二章 创建数据集 本章概要 1探索R数据结构 2使用数据编辑器 3数据导入 4数据集标注 本章所介绍内容概括例如以下. 两个方面的内容. 方面一:R数据结构 方面二:进入数据或者导入数据到数据结构 ...
- SSH-Struts(两)—调节器(ActionServlet)
第一部分介绍的博客Struts架构,下一节介绍中特定成分,这个博客是写Struts控制器ActionServlet. 扮演的角色 ActionServlet类是Struts的控制中心,全部来自于浏览器 ...
- Matlab中调用第三方Java代码
搞了一天,才算搞定. 第一步:定位Matlab中Java环境的ext目录 新建一个M script文件,或者直接在Matlab的交互式命令行中输入: disp(java.lang.System.get ...
- 网络资源(5) - Android视频
2014_08_24 http://v.youku.com/v_show/id_XMjM5NjU2OTI0.html?f=5486194 Android开发视频教程1 http://v.youku.c ...
- 带你轻松玩转Git--瞬间创建本地仓库
在上一篇文章中我们对版本控制有了一个比较宏观的了解,同时也能够看到Git 所处在的历史地位.并且对版本控制系统的体系进行了一个宏观的对比,貌似让读者看起来挺复杂的样子. 笔者将会尽可能的简单向大家分享 ...
- kobject_create_and_add
本文来源于源linux 3.14.3版本号/lib/kobject.c文件 /** * kobject_create_and_add - 动态地创建kobject结构和寄存器sysfs * * ...