文件压缩(二)——英文字符串的处理

文件压缩(一)——Huffman树的构建

在前一篇文章中,我们已经构建了一棵Huffman树了,今天我们将利用这棵Huffman树来实现英文字符串的压缩和解压缩。

一、字符串在JAVA中的储存

String字符串相当于一个char型数组,和C++不同的是,JAVA采用的是unicode编码,每个char型数据占2个字节,只不过对于ASCII码中的字符,它的第一个字节位全0。浪费了一些空间。而存汉字的时候就需要用到两个字节。这里我们为了简便起见,只对ASCII码中的字符进行处理,也就是平常生活中的纯英文文件。因此我们在压缩的过程中只需关注字符的第二个字节位即可。

二、压缩的过程

1.获取字符编码

文件压缩(二)——英文字符串的处理_第1张图片

2.压缩过程

文件压缩(二)——英文字符串的处理_第2张图片

3.解压缩的过程

文件压缩(二)——英文字符串的处理_第3张图片

三、具体的代码(建Huffman树部分的代码见前一篇博客)

//构造Huffman树

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Queue;

public class Huffman {
	
	public static void main(String[] args) {
		//读取相应的字符串		
		String str = "aadefefbcffbaeadde";//待处理的文本
	    HashMap Charmap = new HashMap();
	    //将字符串解析为字符数组
	    char[] arr = str.toCharArray();
	    for (char ch : arr) {
	         //如果找到了相应的字符,则权值加1,否则就把这个字符加到map中
	            if (Charmap.containsKey(ch)) {
	                Integer old = Charmap.get(ch);
	                Charmap.put(ch, old + 1);
	            } else {
	                Charmap.put(ch,1);
	            }
	    }
	    System.out.println(Charmap);	
		
	    //把map中的储存的信息传递给nodes数组,以便建立Huffman树
		List nodes=new ArrayList();
		for(Character key:Charmap.keySet()) {
			Integer value= Charmap.get(key);
			nodes.add(new Node(key,value));
		}
		
		Node root=Huffman.creatTree(nodes);//调用建树函数
		//用一个数组来存储所有的节点信息
		List list=new ArrayList();
		list=Huffman.breadthFirst(root);		
		
		//这里只能用泛型的类型数据,比如int只能用Integer,这里的char只能用Character来代替
		//储存编码的数组
		HashMap map=new HashMap();
		HashMap DecompressMap=new HashMap();
		
		for(int i=0;i
//构架一个压缩文件类
import java.util.HashMap;
public class Compress {
	private static final String Binarytemp = null;
	private static final String String = null;
	public String text;//待压缩的字符串
	public HashMap map=new HashMap();//每个字符所对应的Huffman编码
	public HashMap DecompressMap=new HashMap();//每个字符所对应的Huffman编码
	public String CompressText;//压缩后的文件
	public int CharacterNumber;//用来保存待压缩文件的字符个数
	public String DecompressText="";//解压缩后的文本
	
	//构造函数
	public Compress(String text,HashMap map,HashMap DecompressMap) {
		this.text=text;
		this.map=map;
		this.DecompressMap=DecompressMap;
	}
	
	//定义压缩文件的方法
	public void CompressWay() {
		CharacterNumber=text.length();
		//遍历待压缩的字符串,找出相应的Huffman编码
		String buff="";//保存编码
	    char[] arr = text.toCharArray();
	    for (char ch : arr) {
	         buff=buff+map.get(ch);
	    }
	    //将buff转化为8的整数,不足补0
	    while((buff.length())%8!=0) {
	    	buff=buff+"0";
	    }
	    CompressText="";
	    char[] buffarray = buff.toCharArray();//把buff转化为字符数组
	    for(int i=0;i

四、反思总结

1.我们在把字符转化为相应的二进制序列时,需要将其进行补位,使其变成8的整数,因为每一个字符都是8个bit位。而在解压缩的时候要把补上的无效的0去掉。这里利用了一个int型数据CharacterNumber来保存压缩的字符个数,在解压缩时一旦解压的字符数量已经达到这个数量,则强制退出解压的循环。

2.在利用char型数据的toBinaryString方法把字符转化为二进制时,需要注意char数据在转化为二进制时不会自动在高位补0,它会默认这些高位0是无效位。因此我们需要手动把前面的这些高位0补上去。

你可能感兴趣的:(JAVA,数据结构)