前面讲了如何如何生成哈夫曼树,如何用哈夫曼树进行编码,进而得到哈夫曼哈希表,本节主要讲实例,如何对字符串进行压缩展示。
1、将字符串用生成哈夫曼树,生成哈夫曼哈希表
2、将原byte[]通过哈夫曼哈希表,生成新的byte[],进而压缩了数据
//数据压缩:将字符串压缩
public byte[] zip(byte[] bytes, Map hfmMap) {
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
stringBuilder.append(hfmMap.get(bytes[i]));
}
System.out.println(stringBuilder.toString());
//按照8位一个字节进行压缩
int len = (stringBuilder.length()+7)/8;
byte[] bytes1 = new byte[len];
int index = 0;
for(int i = 0; i < stringBuilder.length(); i += 8) {
if(i+8 < stringBuilder.length()) {
bytes1[index++] = (byte) Integer.parseInt(stringBuilder.substring(i, i+8), 2);
}else {
bytes1[index++] = (byte) Integer.parseInt(stringBuilder.substring(i, stringBuilder.length()), 2);
}
}
return bytes1;
}
package tree.huffmanTree;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.activation.MailcapCommandMap;
public class HuffmanTreeCode {
static Map hashMap = new HashMap();
static StringBuilder stringBuilder = new StringBuilder();
public static void main(String[] args) {
// TODO Auto-generated method stub
//哈夫曼编码:
//构建哈夫曼树节点,包括data(byte),weigth(频率),leftNode,rightNode等
//然后待编译的字符串存放在bytes数组中,并通过map将byte存放在list数组中。
//构建赫夫曼树
HuffmanTreeCode huffmanTreeCode = new HuffmanTreeCode();
String string = "I like like like like like java and do you like it";
byte[] bytes = string.getBytes();
System.out.println(Arrays.toString(bytes));
ArrayList list = huffmanTreeCode.getList(bytes);
HuffmanTreeNode1 huffmanTreeNode1 = huffmanTreeCode.buildHuffmanTree(list);
//前序
// huffmanTreeCode.preOrder(huffmanTreeNode1);
//hfm编码
huffmanTreeCode.hfmCode(huffmanTreeNode1,"",stringBuilder);
// System.out.println(hashMap);
byte[] byte1 = huffmanTreeCode.zip(bytes, hashMap);
System.out.println(Arrays.toString(byte1));
}
//将bytes转化为list
public ArrayList getList(byte[] bytes){
ArrayList list = new ArrayList();
Map hashMap = new HashMap<>();
Integer lenght;
for (int i = 0; i < bytes.length; i++) {
lenght = hashMap.get(bytes[i]);
if(lenght == null) {
hashMap.put(bytes[i], 1);
}else {
hashMap.put(bytes[i], lenght+1);
}
}
for(Map.Entry entry : hashMap.entrySet()) {
list.add(new HuffmanTreeNode1(entry.getKey(),entry.getValue()));
}
return list;
}
//构建哈夫曼树
public HuffmanTreeNode1 buildHuffmanTree(ArrayList list) {
HuffmanTreeNode1 pareNode;
while(list.size() > 1) {
//排序
Collections.sort(list);
//先取出两个最小的元素
pareNode = new HuffmanTreeNode1(null, list.get(0).getWeigth()+list.get(1).getWeigth());
pareNode.setLeftNode(list.get(0));
pareNode.setRightNode(list.get(1));
list.remove(0);
list.remove(0);
list.add(pareNode);
// System.out.println(pareNode.toString());
}
return list.get(0);
}
//前序遍历
public void preOrder(HuffmanTreeNode1 node) {
if(node == null) {
return;
}
node.preOrder();
}
//
//hfm编码
public void hfmCode(HuffmanTreeNode1 node, String aString, StringBuilder stringBuilder) {
StringBuilder stringBuilder2 = new StringBuilder(stringBuilder);
stringBuilder2.append(aString);
//判断是不是叶子节点
if(node.getData() == null) {//非叶子节点
hfmCode(node.getLeftNode(), "0", stringBuilder2);
hfmCode(node.getRightNode(), "1", stringBuilder2);
}else {
hashMap.put(node.getData(), stringBuilder2);
}
}
//数据压缩:将字符串压缩
public byte[] zip(byte[] bytes, Map hfmMap) {
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
stringBuilder.append(hfmMap.get(bytes[i]));
}
System.out.println(stringBuilder.toString());
//按照8位一个字节进行压缩
int len = (stringBuilder.length()+7)/8;
byte[] bytes1 = new byte[len];
int index = 0;
for(int i = 0; i < stringBuilder.length(); i += 8) {
if(i+8 < stringBuilder.length()) {
bytes1[index++] = (byte) Integer.parseInt(stringBuilder.substring(i, i+8), 2);
}else {
bytes1[index++] = (byte) Integer.parseInt(stringBuilder.substring(i, stringBuilder.length()), 2);
}
}
return bytes1;
}
}
class HuffmanTreeNode1 implements Comparable{
private Byte data;
private Integer weigth;
private HuffmanTreeNode1 leftNode;
private HuffmanTreeNode1 rightNode;
public HuffmanTreeNode1(Byte data, int weigth ) {
this.data = data;
this.weigth = weigth;
}
public Byte getData() {
return data;
}
public void setData(byte data) {
this.data = data;
}
public int getWeigth() {
return weigth;
}
public void setWeigth(int weigth) {
this.weigth = weigth;
}
public HuffmanTreeNode1 getLeftNode() {
return leftNode;
}
public void setLeftNode(HuffmanTreeNode1 leftNode) {
this.leftNode = leftNode;
}
public HuffmanTreeNode1 getRightNode() {
return rightNode;
}
public void setRightNode(HuffmanTreeNode1 rightNode) {
this.rightNode = rightNode;
}
@Override
public String toString() {
return "HuffmanTreeNode1 [data=" + data + ", weigth=" + weigth + "]";
}
//前序遍历
public void preOrder() {
System.out.println(this.toString());
if(this.leftNode != null) {
this.leftNode.preOrder();
}
if(this.rightNode != null) {
this.rightNode.preOrder();
}
}
@Override
public int compareTo(HuffmanTreeNode1 o) {
// TODO Auto-generated method stub
return this.getWeigth() - o.getWeigth();//升序
}
}