package huffmancode;
import org.omg.CORBA.INTERNAL;
import java.util.*;
/**
* @author Xiaotong Xu
* @create 2021-06-19 16:14
*/
public class HuffmanCode {
public static void main(String[] args) {
String str = "i like like like java do you like a java";
byte[] bytes = huffmanZip(str);
System.out.println(Arrays.toString(bytes));
byte[] bytes1 = byteToString(huffmanCode, bytes);
System.out.println(new String(bytes1));
}
//解码
public static byte[] byteToString(Map<Byte, String> huffmanCode, byte[] bytes) {
StringBuilder builder = new StringBuilder();
String s;
for (int i = 0; i < bytes.length; i++) {
int ints = bytes[i]; //补码
if (i != bytes.length - 1) {
ints |= 256; //补位处理
s = Integer.toBinaryString(ints); //转换为ints形式的补码
s=s.substring(s.length()-8);
} else {
s = Integer.toBinaryString(ints);
}
builder.append(s);
}
Map<String,Byte> map=new HashMap<>();
List<Byte> list=new ArrayList();
for(Map.Entry<Byte,String> entry :huffmanCode.entrySet()){
map.put(entry.getValue(),entry.getKey());
}
for(int i=0;i<builder.length();){
int count=0;
boolean flag=true;
while(flag){
String s1=builder.substring(i,i+count);
if(map.get(s1)==null){
count++;
}else{
list.add(map.get(s1));
flag=false;
}
}
i=i+count;
}
byte[] bytesDecode=new byte[list.size()];
for(int i=0;i<list.size();i++){
bytesDecode[i]=list.get(i);
}
return bytesDecode;
}
//封装编码所有方法
public static byte[] huffmanZip(String str) {
//创建哈夫曼树
Node huffmanTree = createHuffmanTree(str);
//转换为哈夫曼编码
Map<Byte, String> huffmanCode = createHuffmanCode(huffmanTree);
//转换为二进制压缩编码
byte[] bytes = huffmanCodeZip(str, huffmanCode);
return bytes;
}
//压缩数据
public static byte[] huffmanCodeZip(String str, Map<Byte, String> huffmanCode) {
byte[] bytes = str.getBytes();
StringBuilder builder = new StringBuilder();
for (byte b : bytes) {
builder.append(huffmanCode.get(b));
}
int len = (builder.length() + 7) / 8;
byte[] huffmanZipByte = new byte[len];
int index = 0;
for (int i = 0; i < builder.length(); i += 8) {
if (i + 8 > builder.length()) {
huffmanZipByte[index] = (byte) Integer.parseInt(builder.substring(i), 2);
//转换为byte,将数字看成要转换的byte型的带符号的补码
} else {
huffmanZipByte[index] = (byte) Integer.parseInt(builder.substring(i, i + 8), 2);
index++;
}
}
return huffmanZipByte;
}
//创造二进制编码
static StringBuilder builder = new StringBuilder();
static Map<Byte, String> huffmanCode = new HashMap<>();
public static Map<Byte, String> createHuffmanCode(Node root) {
if (root == null) {
System.out.println("此二叉树为空");
return null;
} else {
createHuffmanCode(root.left, "0", builder);
createHuffmanCode(root.right, "1", builder);
}
return huffmanCode;
}
public static void createHuffmanCode(Node node, String code, StringBuilder stringBuilder) {
StringBuilder builder1 = new StringBuilder(stringBuilder);
builder1.append(code);
if (node != null) {
if (node.value == null) {
createHuffmanCode(node.left, "0", builder1);
createHuffmanCode(node.right, "1", builder1);
} else {
huffmanCode.put(node.value, builder1.toString());
}
}
}
//传入数据 得到哈夫曼树
public static Node createHuffmanTree(String str) {
byte[] content = str.getBytes();
Map<Byte, Integer> map = new HashMap<>();
for (Byte b : content) {
Integer count = map.get(b);
if (count == null) {
map.put(b, 1);
} else {
map.put(b, count + 1);
}
}
List<Node> nodes = new ArrayList();
for (Map.Entry<Byte, Integer> entry : map.entrySet()) {
Node node = new Node(entry.getKey(), entry.getValue());
nodes.add(node);
}
while (nodes.size() > 1) {
Collections.sort(nodes);
Node leftNode = nodes.get(0);
Node rightNode = nodes.get(1);
Node parent = new Node(null, rightNode.wight + leftNode.wight);
parent.left = leftNode;
parent.right = rightNode;
nodes.remove(rightNode);
nodes.remove(leftNode);
nodes.add(parent);
}
return nodes.get(0);
}
public static void proOrder(Node root) {
if (root == null) {
System.out.println("此二叉树为空");
} else {
root.proOrder();
}
}
}
class Node implements Comparable<Node> {
int wight;
Byte value;
Node left;
Node right;
public Node(Byte value, int wight) {
this.wight = wight;
this.value = value;
}
public void proOrder() {
System.out.println(this);
if (this.left != null) {
this.left.proOrder();
}
if (this.right != null) {
this.right.proOrder();
}
}
@Override
public String toString() {
return "Node{" +
"wight=" + wight +
", value=" + value +
'}';
}
@Override
public int compareTo(Node o) {
return this.wight - o.wight;
}
}
哈夫曼编码 Java
最新推荐文章于 2022-09-06 14:26:47 发布