您现在的位置是:首页 > 后台技术 > 数据结构与算法数据结构与算法

赫夫曼编码解码(图文)

第十三双眼睛2023-10-20【数据结构与算法】人已围观

简介赫夫曼编码解码

赫夫曼编码解码
package com.xingchen.day012;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class HuffManCode {
    public static void main(String[] args) {
        String s = "i like like like java do you like a java";
        byte[] bytes = s.getBytes();
        //System.out.println(bytes.length);
        //List<Node> nodes = getNodes(bytes);
        //System.out.println(nodes);
        //Node huffManTree = createHuffManTree(nodes);
        //Map<Byte, String> codeMap = getCodes(huffManTree, "", stringBuilder);
        //byte[] zip = zip(bytes, codeMap);
        byte[] zip = huffManZip(bytes);
        //System.out.println(Arrays.toString(zip));
        byte[] decode = decode(codeMap, zip);
        System.out.println(Arrays.toString(decode));
        System.out.println(new String(decode));
    }
    public static byte[] huffManZip(byte[] bytes) {
        List<Node> nodes = getNodes(bytes);
        Node huffManTree = createHuffManTree(nodes);
        Map<Byte, String> codeMap = getCodes(huffManTree, "", stringBuilder);

        byte[] zip = zip(bytes, codeMap);
        return zip;
    }
    public static byte[] decode(Map<Byte,String> codeMap, byte[] bytes) {
        StringBuilder stringBuilder1 = new StringBuilder();
        for (int i=0;i < bytes.length;i ++) {
            boolean flag = (bytes.length - 1) == i;
            stringBuilder1.append(byte2BitString(!flag,bytes[i]));
        }
        System.out.println(stringBuilder1.toString());
        Map<String,Byte> map = new HashMap<>();
        for (Map.Entry<Byte,String> entry: codeMap.entrySet()) {
            map.put(entry.getValue(), entry.getKey());
        }
        List<Byte> list = new ArrayList<>();
        for (int i=0;i<stringBuilder1.length();) {
            int count = 1;
            boolean flag = true;
            Byte b = null;
            while (flag) {
                String key = stringBuilder1.substring(i, i + count);
                b = map.get(key);
                if (b == null) {
                    count +=1;
                } else {
                    flag = false;
                }
            }
            list.add(b);
            i += count;
        }
        byte[] b = new byte[list.size()];
        for (int i = 0; i<b.length; i++) {
            b[i] = list.get(i);
        }
        return b;
    }
    // 文件的压缩
    public static void zipFile(String srcFile,String destFile) {
        FileInputStream inputStream = null;
        FileOutputStream outputStream = null;
        ObjectOutputStream objectOutputStream = null;
        try {
            inputStream = new FileInputStream(srcFile);
            byte[] b = new byte[inputStream.available()];
            inputStream.read(b);
            byte[] bytes = huffManZip(b);
            outputStream = new FileOutputStream(destFile);
            objectOutputStream = new ObjectOutputStream(outputStream);
            objectOutputStream.writeObject(bytes);
            objectOutputStream.writeObject(codeMap);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    public static void unzip(String zipFile,String destFile) {
        InputStream inputStream = null;
        OutputStream outputStream = null;
        ObjectInputStream objectInputStream = null;
        try {
            inputStream = new FileInputStream(zipFile);
            objectInputStream = new ObjectInputStream(inputStream);
            byte[] b = (byte[]) objectInputStream.readObject();
            Map<Byte,String> codeMap = (Map)objectInputStream.readObject();
            byte[] decode = decode(codeMap, b);
            outputStream = new FileOutputStream(destFile);
            outputStream.write(decode);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static String byte2BitString(boolean flag,byte b) {
        int temp = b;
        if (flag) {
            temp |= 256;
        }
        String binaryString = Integer.toBinaryString(temp);
        if (flag) {
            return binaryString.substring(binaryString.length() - 8);
        }
        return binaryString;
    }
    public static byte[] zip(byte[] bytes, Map<Byte,String> codeMap) {
        StringBuilder builder = new StringBuilder();
        for (byte b :bytes) {
            builder.append(codeMap.get(b));
        }
        int length = 0;
        if (builder.length()%8 == 0) {
            length = builder.length()/8;
        } else {
            length = builder.length()/8 + 1;
        }
        int index = 0;
        byte[] by = new byte[length];
        for (int i = 0 ;i< builder.length();i+=8) {
            String bystring = "";
            if (i+ 8 >builder.length()) {
                bystring = builder.substring(i);
            } else {
                bystring = builder.substring(i,i + 8);
            }
            by[index] = (byte) Integer.parseInt(bystring, 2);
            index ++;
        }
        return by;
    }
    public static List<Node> getNodes(byte[] arr) {
        List<Node> list = new ArrayList<>();
        //存储每一个字符出现的次数
        Map<Byte, Integer> map = new HashMap<>();
        for (byte b : arr) {
            Integer count = map.get(b);
            if (count == null) {
                map.put(b, 1);
            } else {
                map.put(b, count + 1);
            }
        }
        //将每一个键值堆转换成Node
        for (Map.Entry<Byte,Integer> entry : map.entrySet()) {
            list.add(new Node(entry.getKey(),entry.getValue()));
        }
        return list;
    }
    public static Node createHuffManTree(List<Node> list) {
        while (list.size() > 1) {
            Collections.sort(list);
            //取出最小的
            Node left = list.get(0);
            Node right = list.get(1);
            //创建一个新的节点,,没有data
            Node parent = new Node(null,left.weight + right.weight);
            parent.left = left;
            parent.right = right;
            list.remove(left);
            list.remove(right);
            list.add(parent);
        }
        return list.get(0);
    }
    static Map<Byte,String> codeMap = new HashMap<>();
    static StringBuilder stringBuilder = new StringBuilder();
    public static Map<Byte,String> getCodes(Node node,String code,StringBuilder stringBuilder) {
        StringBuilder builder2 = new StringBuilder(stringBuilder);
        builder2.append(code);
        if (code != null) {
            if (node.data == null) {
                //向左递归
                getCodes(node.left,"0",builder2);
                //向右递归
                getCodes(node.right,"1",builder2);
            } else {
                codeMap.put(node.data,builder2.toString());
            }
        }
        return codeMap;
    }
}
class Node implements Comparable<Node>{
    public Byte data;
    public int weight;
    public Node left;
    public Node right;
    public Node(Byte data, int weight) {
        this.data = data;
        this.weight = weight;
    }
    @Override
    public String toString() {
        return "Node{" +
                "data=" + data +
                ", weight=" + weight +
                '}';
    }
    public void preOrder() {
        System.out.println(this);
        if (this.left != null) {
            this.left.preOrder();
        }
        if (this.right != null) {
            this.right.preOrder();
        }
    }
    @Override
    public int compareTo(Node o) {
        return this.weight - o.weight;
    }
}

Tags:

很赞哦! ()

文章评论

    共有条评论来说两句吧...

    用户名:

    验证码:

本站推荐

站点信息

  • 网站名称:JavaStudy
  • 建站时间:2019-1-14
  • 网站程序:帝国CMS7.5
  • 文章统计242篇文章
  • 标签管理标签云
  • 统计数据百度统计
  • 微信公众号:扫描二维码,关注我们