哈夫曼编码解码
程序员文章站
2022-03-25 15:43:43
哈夫曼编码解码zip将 String 的原始字节数组转换成哈夫曼编码处理后的字节数组通过 哈夫曼编码表 获取 byte 对应的 value步长为 8 对StringBuffer进行分割,最后一位不满8位则直接存储通过 Integer.parseInt( , 2) 进行转换byteToBinaryString通过传入 byte 字节 和 是否为 最后一位 flagtemp |= 256 补高位decode哈夫曼解码传入 哈夫曼编码处理后的 字节数组、哈夫曼编码表原始字节数....
哈夫曼编码解码
zip
- 将 String 的原始字节数组转换成哈夫曼编码处理后的字节数组
- 通过 哈夫曼编码表 获取 byte 对应的 value
- 步长为 8 对StringBuffer进行分割,最后一位不满8位则直接存储
- 通过 Integer.parseInt( , 2) 进行转换
byteToBinaryString
- 通过传入 byte 字节 和 是否为 最后一位 flag
- temp |= 256 补高位
decode
- 哈夫曼解码
- 传入 哈夫曼编码处理后的 字节数组、哈夫曼编码表
- 原始字节数组字符串拼接
- codeMap 哈夫曼编码表 反转
- 步长为 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
上一篇: JS面向对象之多选框实现