算法学习(十)——赫夫曼编码用于数据压缩

定长编码&变长编码

定长编码
在这里插入图片描述
变长编码

在这里插入图片描述

赫夫曼编码介绍

概念介绍

  1. 赫夫曼编码也翻译为 哈夫曼编码(Huffman Coding), 又称霍夫曼编码, 是一种编码方式, 属于一种程序算法
  2. 赫夫曼编码是赫哈夫曼树在电讯通信中的经典的应用之一。
  3. 赫夫曼编码广泛地用于数据文件压缩。 其压缩率通常在 20%~90%之间
  4. 赫夫曼码是可变字长编码(VLC)的一种。 Huffman 于 1952 年提出一种编码方法, 称之为最佳编码。

实现流程

  1. 首先准备一个要压缩的字符串i like like like java do you like a java

  2. 然后统计各个字符对应的个数
    d:1 y:1 u:1 j:2 v:2 o:2 l:4 k:4 e:4 i:5 a:5 空格:9

  3. 按照上面字符出现的次数构建一颗赫夫曼树, 次数作为权值

关于赫夫曼树这里不做介绍了,详情参见我的这篇博客赫夫曼树

构建好的赫夫曼树如下
在这里插入图片描述

  1. 根据赫夫曼树, 给各个字符,规定编码 (前缀编码), 向左的路径为 0 向右的路径为 1 , 编码如下:

    o: 1000 u: 10010 d: 100110 y: 100111 i: 101 a : 110 k: 1110 e: 1111 j: 0000 v: 0001 l: 001 : 01

  2. 按照上面的赫夫曼编码, 我们的"i like like like java do you like a java" 字符串对应的编码为 (注意这里我们使用的无损压缩,即可以完全解压成原本的形式)
    1010100110111101111010011011110111101001101111011110100001100001110011001111000011001111000100100100110111101111011100100001100001110 通过赫夫曼编码处理长度为 133,原来长度359,压缩了 (359-133) / 359 = 62.9%

代码实现

注意,代码里还有许多程序的技巧,比如按位与求正数的byte数据,还包括了解压的过程,供后面复习使用。

package com.tunan.huffmancode;

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 str = "i like like like java do you like a java";
		byte[] strBytes = str.getBytes();
		System.out.println("字符串长度(含空格)"+strBytes.length);
		
		//压缩
		byte[] huffmanZip = huffmanZip(strBytes);
		//解压
		byte[] decodeRes = decode(huffmanCodes, huffmanZip);
		System.out.println("解压后的字符串是:"+ new String(decodeRes));
	}
	
	
	//编写解压过程
	//1.赫夫曼编码转成二进制字符串
	/**
	 * 
	 * @param flag表示是否需要补高位  如果是最后一个字节,无需补高位
	 * @param b表示传入的字节数
	 * @return
	 */
	private static String byteTobinString(boolean flag, byte b) {
   
		int temp = b;
		//如果是正数,则需进行补高位处理
		if(flag) {
   
			temp |= 256;//按位与256 	1000 0000 | 0000 0001 = 1000 0001
		}
		
		
		String res = Integer.toBinaryString(temp);
		if(flag) {
   
			return res.substring(res.length() - 8);
		}else {
   
			return res;
		}
	}
	
	//2.将二进制字符串转成字符
	/**
	 * 
	 * @param huffmanCodes 赫夫曼编码编码表
	 * @param huffmanBytes 赫夫曼编码
	 * @return
	 */
	private static byte[] decode(Map<Byte, String
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值