33、哈夫曼解压(有问题,待解决)

哈夫曼编码的时候,我们得到了哈夫曼哈希表编码后的字节数组,我们根据这两个,便可以进行解码。

  • 思路:

1、首先将字节数组转化为二进制字符串:

/**
 *  将一个byte 转成一个二进制的字符串, 如果看不懂,可以参考我讲的Java基础 二进制的原码,反码,补码
 * @param b 传入的 byte
 * @param flag 标志是否需要补高位如果是true ,表示需要补高位,如果是false表示不补, 如果是最后一个字节,无需补高位
 * @return 是该b 对应的二进制的字符串,(注意是按补码返回)
 */
private static String byteToBitString(boolean flag, byte b) {
	//使用变量保存 b
	int temp = b; //将 b 转成 int
	//如果是正数我们还存在补高位
	if(flag) {
		temp |= 256; //按位与 256  1 0000 0000  | 0000 0001 => 1 0000 0001
	}
	String str = Integer.toBinaryString(temp); //返回的是temp对应的二进制的补码
	if(flag) {
		return str.substring(str.length() - 8);
	} else {
		return str;
	}
}

2、根据哈夫曼哈希表,将二进制数组翻译成原字节数组(注:应该讲哈夫曼哈希表里的key和value翻转,这样才能依据二进制字符串得到字节数组):

//将赫夫曼编码的数据解码
@SuppressWarnings("unlikely-arg-type")
public static byte[] decode(Map<Byte, String> hfmMap,byte[] hfmbytes) {
	System.out.println(Arrays.toString(hfmbytes));
	//1、先得到赫夫曼编码对应的二进制字符串
	StringBuilder stringBuilder = new StringBuilder();
	boolean flage;
	for (int i = 0; i < hfmbytes.length; i++) {
		flage = (i == hfmbytes.length - 1);
		stringBuilder.append(byteToBitString(!flage, hfmbytes[i]));
	}
	System.out.println(stringBuilder.toString());
	
	//2、将赫夫曼哈希表key和value调换位置
	Map<String, Byte> haspMap1 = new HashMap<String, Byte>();
	for (Map.Entry<Byte, String> entry : hfmMap.entrySet()) {
		haspMap1.put(entry.getValue()+"", entry.getKey());
	}
	System.out.println(hfmMap.toString());
	System.out.println(haspMap1.toString());
	//3、将二进制的哈夫曼编码用赫夫曼哈希表(key和value已经调换位置)解析
    //byte[] bytes2 = new byte[];
	List<Byte> list = new ArrayList<Byte>();

	for(int i = 0; i < stringBuilder.length();) {
		int count = 1;//指针
		Byte byte1 = null;
		while(true) {
			String key = stringBuilder.substring(i,i+count);
			byte1 = haspMap1.get(key);
			if(byte1 == null) {//还未找到
				count++;
			}else {
				break;
			}
		}
		list.add(byte1);
			
		i += count;
		
		
	}
	
	byte[] bytes2 = new byte[list.size()];
	for (int i = 0; i < bytes2.length; i++) {
		bytes2[i] = list.get(i);
	}
	return bytes2;
	
}

3、打印字节数组成字符串即可:

byte[] d =  decode(hashMap, byte1);
System.out.println(new String(d));
  • 问题:

我发现如果哈夫曼编码后的二进制字符串如果最后的子字符串不满8位时,若为0111,则直接转化为了7,但是再次解码时,7被解码成了111,此时0便消失不见了,所以有的时候,哈夫曼解码时会有问题(尾部少数据)。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值