欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

哈夫曼编码解码

程序员文章站 2022-03-25 15:43:43
哈夫曼编码解码zip将 String 的原始字节数组转换成哈夫曼编码处理后的字节数组通过 哈夫曼编码表 获取 byte 对应的 value步长为 8 对StringBuffer进行分割,最后一位不满8位则直接存储通过 Integer.parseInt( , 2) 进行转换byteToBinaryString通过传入 byte 字节 和 是否为 最后一位 flagtemp |= 256 补高位decode哈夫曼解码传入 哈夫曼编码处理后的 字节数组、哈夫曼编码表原始字节数....

哈夫曼编码解码

zip

  1. 将 String 的原始字节数组转换成哈夫曼编码处理后的字节数组
  2. 通过 哈夫曼编码表 获取 byte 对应的 value
  3. 步长为 8 对StringBuffer进行分割,最后一位不满8位则直接存储
  4. 通过 Integer.parseInt( , 2) 进行转换

byteToBinaryString

  1. 通过传入 byte 字节 和 是否为 最后一位 flag
  2. temp |= 256 补高位

decode

  1. 哈夫曼解码
  2. 传入 哈夫曼编码处理后的 字节数组、哈夫曼编码表
  3. 原始字节数组字符串拼接
  4. codeMap 哈夫曼编码表 反转
  5. 步长为 8 对 sb 进行解析、解析出的 Byte temp 存入 List<Byte>
    public static void main(String[] args) {
        // 数据压缩
        String str = "i like like like java do you like a java";

        List<hufNode> nodes = strToList(str);

        hufNode root = createHufmanTree(nodes);

        getCodes(root, "", context);
        
        byte[] bytes = str.getBytes();
        byte[] zip = zip(bytes, codeMap);
        System.out.println(Arrays.toString(zip));


        byte[] decode = decode(codeMap, zip);
        System.out.println(new String(decode));

    }





    /**
     * 将原始的字节数组转换成哈夫曼编码处理后的字节数组
     *
     * @param bytes 原始的字节数组
     * @return 哈夫曼编码处理后的字节数组
     */
    public static byte[] zip(byte[] bytes, Map<Byte, String> codeMap) {
        StringBuffer sb = new StringBuffer();
        for (byte b : bytes) {
            // 拼接到 sb 中
            sb.append(codeMap.get(b));
        }
        int len = 0;
        // 步长 8 位截取转换
        if (sb.length() % 8 == 0) {
            len = sb.length() / 8;
        } else {
            len = sb.length() / 8 + 1;
        }
        // 等价于
//        len = (sb.length() + 7) / 8;
        byte[] res = new byte[len];
        int index = 0;
        for (int i = 0; i < sb.length(); i = i + 8) {
            String strByte;
            if (i + 8 > sb.length()) {
                // 最后一个不够 8 位
                strByte = sb.substring(i);
            } else {
                strByte = sb.substring(i, i + 8);  // 截取8位
            }
            // 按二进制转换成int
            res[index++] = (byte) Integer.parseInt(strByte, 2);
        }

        return res;
    }


    /**
     *  解压:
     *     根据哈夫曼编码表解压回字符串
     * @param codeMap
     * @param bytes  编码处理后的字节数组
     */
    public static byte[] decode(Map<Byte, String> codeMap, byte[] bytes) {
        StringBuffer sb = new StringBuffer();

        // 原始字节数组字符串拼接
        for (int i = 0 ; i < bytes.length ; i++){
            boolean flag = (i == bytes.length - 1);
            String str = byteToStringBuffer(bytes[i], flag);
            //
            sb.append(str);
        }

        Map<String, Byte> map = new HashMap<>();
        // 反转
        for (Map.Entry<Byte , String> e : codeMap.entrySet()){
            map.put(e.getValue(), e.getKey());
        }

        List<Byte> list = new ArrayList<>();
        // 解释
        for (int i = 0; i < sb.length() ; ){
            int count = 1;
            while(true){
                Byte temp = map.get(sb.substring(i, i + count));
                if(temp == null){
                    count++;
                } else {
                    list.add(temp);
                    break ;
                }
            }
            i = i + count;
        }

        // 换回 byte 数组
        byte[] res = new byte[list.size()];
        for (int i = 0 ; i < res.length ; i++){
            res[i] = list.get(i);
        }

        return res;
    }


    /**
     * 将压缩的哈夫曼编码处理后的字节数组 转换成 原始的字节数组
     *
     * @param b 传入的 byte
     * @param flag  判断是否需要补高位
     * @return 该 b 的对应的二进制字符串(补码的形式返回)
     */
    public static String byteToStringBuffer(byte b, boolean flag) {
        int temp;
        temp = b;
        if (!flag) {
            // 补高位
            temp |= 256;
        }
        String str = Integer.toBinaryString(temp);
        if (flag) {
            return str;
        } else {
            return str.substring(str.length() - 8); // 返回后8 位
        }
    }


本文地址:https://blog.csdn.net/qq_43765535/article/details/107690039