生活随笔
收集整理的這篇文章主要介紹了
算法系列之使用赫夫曼编码的实战应用【对文件进行压缩、解压缩】
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1.首先在準備一張圖片
2.測試壓縮效果
3.測試解壓縮效果
將桌面a.jpg刪除
4.源代碼
package com.zsh.algorithm.tree;import java.io.*;
import java.util.*;public class HuffmanEncrypt {public static void main(String[] args
) {
fileDecode("C:\\Users\\18179\\Desktop\\a.zip", "C:\\Users\\18179\\Desktop\\a.jpg");}private static StringBuilder stringBuilder
= new StringBuilder();private static Map<Byte, String> huffmanCodesMap
= new HashMap<>();public static byte[] huffmanZip(byte[] bytes
) {List<EncryptNode> encryptNodeList
= calByteNums(bytes
);EncryptNode root
= buildHuffmanTree(encryptNodeList
);Map<Byte, String> huffmanCodes
= getHuffmanCodes(root
);return zip(bytes
, huffmanCodes
);}public static List<EncryptNode> calByteNums(byte[] bytes
) {Map<Byte, Integer> map
= new HashMap<>();byte[] charArray
= bytes
;for (byte c
: charArray
) {if (map
.containsKey(c
)) {int num
= map
.get(c
);map
.replace(c
, num
, num
+ 1);} else {map
.put(c
, 1);}}List<EncryptNode> list
= new ArrayList<>();for (Map.Entry<Byte, Integer> entry
: map
.entrySet()) {Byte key
= entry
.getKey();Integer value
= entry
.getValue();list
.add(new EncryptNode(key
, value
));}return list
;}public static EncryptNode buildHuffmanTree(List<EncryptNode> list
) {while (list
.size() > 1) {Collections.sort(list
);EncryptNode leftNode
= list
.remove(0);EncryptNode rightNode
= list
.remove(0);EncryptNode parentNode
= new EncryptNode(null, leftNode
.value
+ rightNode
.value
);parentNode
.left
= leftNode
;parentNode
.right
= rightNode
;list
.add(parentNode
);}return list
.remove(0);}public static Map<Byte, String> getHuffmanCodes(EncryptNode root
) {if (root
== null) {return null;} else {getHuffmanCodes(root
.left
, "0", stringBuilder
);getHuffmanCodes(root
.right
, "1", stringBuilder
);}return huffmanCodesMap
;}public static void getHuffmanCodes(EncryptNode node
, String path
, StringBuilder stringBuilder
) {StringBuilder stringBuilder2
= new StringBuilder(stringBuilder
);stringBuilder2
.append(path
);if (node
!= null) {if (node
.c
== null) {getHuffmanCodes(node
.left
, "0", stringBuilder2
);getHuffmanCodes(node
.right
, "1", stringBuilder2
);} else {huffmanCodesMap
.put(node
.c
, stringBuilder2
.toString());}}}public static byte[] zip(byte[] bytes
, Map<Byte, String> entry
) {StringBuilder stringBuilder
= new StringBuilder();for (byte ch
: bytes
) {stringBuilder
.append(entry
.get(ch
));}int length
= stringBuilder
.length();int len
= (length
+ 7) / 8;byte[] huffmanCodeBytes
= new byte[len
];int index
= 0;for (int k
= 0; k
< length
; k
+= 8) {String str
;if ((k
+ 8) > length
) {str
= stringBuilder
.substring(k
);} else {str
= stringBuilder
.substring(k
, k
+ 8);}huffmanCodeBytes
[index
] = (byte) Integer.parseInt(str
, 2);index
++;}return huffmanCodeBytes
;}public static String calHuffmanZipRatio(byte[] original
, byte[] newByte
) {double zipRatio
= (double) (original
.length
- newByte
.length
) / original
.length
* 100;String s
= String.format("%.2f", zipRatio
);return s
+ "%";}private static byte[] decode(Map<Byte, String> huffmanCodesMap
, byte[] bytes
) {StringBuilder stringBuilder
= new StringBuilder();for (int k
= 0; k
< bytes
.length
; k
++) {boolean flag
= (k
== bytes
.length
- 1);stringBuilder
.append(byteToBinaryString(!flag
, bytes
[k
]));}Map<String, Byte> reverseMap
= new HashMap<>();for (Map.Entry<Byte, String> map
: huffmanCodesMap
.entrySet()) {reverseMap
.put(map
.getValue(), map
.getKey());}List<Byte> list
= new ArrayList<>();for (int i
= 0; i
< stringBuilder
.length(); ) {int count
= 1;Byte b
= null;boolean flag
= true;while (flag
) {String key
= stringBuilder
.substring(i
, i
+ count
);b
= reverseMap
.get(key
);if (b
== null) {count
++;} else {flag
= false;}}list
.add(b
);i
+= count
;}byte[] result
= new byte[list
.size()];for (int k
= 0; k
< result
.length
; k
++) {result
[k
] = list
.get(k
);}return result
;}private static String byteToBinaryString(boolean flag
, byte be
) {int beInt
= be
;if (flag
) {beInt
|= 256; }String s
= Integer.toBinaryString(beInt
); if (flag
) {return s
.substring(s
.length() - 8);} else {return s
;}}private static void fileEncode(String readFile
, String storeFile
) {FileInputStream is
= null;ObjectOutputStream oos
= null;FileOutputStream os
= null;try {is
= new FileInputStream(readFile
);byte[] bytes
= new byte[is
.available()];is
.read(bytes
);byte[] huffmanBytes
= huffmanZip(bytes
);os
= new FileOutputStream(storeFile
);oos
= new ObjectOutputStream(os
);oos
.writeObject(huffmanBytes
);oos
.writeObject(huffmanCodesMap
);os
.write(huffmanBytes
);} catch (FileNotFoundException e
) {e
.printStackTrace();} catch (IOException e
) {e
.printStackTrace();} finally {try {oos
.close();os
.close();is
.close();} catch (IOException e
) {e
.printStackTrace();}}}public static void fileDecode(String zipFile
, String dstFile
) {System.out
.println("文件解壓開始----------------------");FileInputStream is
= null;ObjectInputStream ois
= null;FileOutputStream os
= null;try {is
= new FileInputStream(zipFile
);ois
= new ObjectInputStream(is
);byte[] huffmanBytes
= (byte[])ois
.readObject();Map<Byte, String> huffmanCodes
= (Map<Byte, String>) ois
.readObject();byte[] bytes
= decode(huffmanCodes
, huffmanBytes
);os
= new FileOutputStream(dstFile
);os
.write(bytes
);} catch (FileNotFoundException e
) {e
.printStackTrace();} catch (IOException e
) {e
.printStackTrace();} catch (ClassNotFoundException e
) {e
.printStackTrace();} finally {try {os
.close();ois
.close();is
.close();} catch (IOException e
) {e
.printStackTrace();}}}public static void preErgodic(EncryptNode cur
) {if (cur
== null) {return;}System.out
.println(cur
);preErgodic(cur
.left
);preErgodic(cur
.right
);}public static <T> void outputList(List<T> list
) {for (T t
: list
) {System.out
.println(t
);}}
}
class EncryptNode implements Comparable<EncryptNode> {public int value
; public Byte c
; public EncryptNode left
;public EncryptNode right
;public EncryptNode(int value
) {this.value
= value
;}public EncryptNode(Byte c
, int value
) {this.value
= value
;this.c
= c
;}@Overridepublic int compareTo(EncryptNode o
) {return this.value
- o
.value
; }@Overridepublic String toString() {return "EncryptNode{" +"value=" + value
+", c=" + c
+'}';}
}
結束~
總結
以上是生活随笔為你收集整理的算法系列之使用赫夫曼编码的实战应用【对文件进行压缩、解压缩】的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。