public class HuffManCodeCus {
public static void main(String[] args) {
HuffManCodeCus huffManCodeCus = new HuffManCodeCus();
String msg = " can you think about it?";
huffManCodeCus.huffManCodeCus(msg);
}
public void huffManCodeCus(String str){
byte[] bytes = str.getBytes();
System.out.println("压缩前:"+bytes.length);
System.out.println(Arrays.toString(bytes));
List<Node> nodes = createNodeList(bytes);
Node tree = createTree(nodes);
Map<Byte,String> huffManCodeTable = createCode(tree);
System.out.println(huffManCodeTable);
byte[] zipBytes = zip(huffManCodeTable,bytes);
System.out.println("压缩前:"+zipBytes.length);
}
private byte[] zip(Map<Byte, String> huffManCodeTable, byte[] bytes) {
StringBuilder zipSb = new StringBuilder();
for (int i=0;i<bytes.length;i++){
zipSb.append(huffManCodeTable.get(bytes[i]));
}
int len;
if (zipSb.length()%8 ==0){
len = zipSb.length()/8;
}else {
len = zipSb.length()/8+1;
}
byte[] zipResbytes = new byte[len];
int index = 0;
for (int i=0;i<zipSb.length();i=i+8){
String temp = "";
if (zipSb.length()-i<8){
temp = zipSb.substring(i);
}else {
temp = zipSb.substring(i,i+8);
}
byte b = (byte) Integer.parseInt(temp,2);
zipResbytes[index] = b;
index++;
}
return zipResbytes;
}
static StringBuilder sb = new StringBuilder();
static Map<Byte, String> huffManMap = new HashMap<>();
private Map<Byte, String> createCode(Node tree) {
if (tree == null){
return null;
}
createCodes(tree.left,"0",sb);
createCodes(tree.right,"1",sb);
return huffManMap;
}
private void createCodes(Node node, String s, StringBuilder sb) {
StringBuilder stringBuilder = new StringBuilder(sb);
stringBuilder.append(s);
if (node.data==null){
createCodes(node.left,"0",stringBuilder);
createCodes(node.right,"1",stringBuilder);
}else {
huffManMap.put(node.data,stringBuilder.toString());
}
}
private Node createTree(List<Node> nodes) {
while (nodes.size()>1) {
Collections.sort(nodes);
Node left = nodes.get(nodes.size() - 1);
Node right = nodes.get(nodes.size() - 2);
Node parent = new Node(null, left.weight + right.weight);
parent.left = left;
parent.right = right;
nodes.remove(left);
nodes.remove(right);
nodes.add(parent);
}
return nodes.get(0);
}
private List<Node> createNodeList(byte[] bytes) {
List<Node> nodes = new ArrayList<>();
Map<Byte,Integer> map = new HashMap<>();
for (int i=0;i<bytes.length;i++){
if (map.get(bytes[i])==null){
map.put(bytes[i],1);
}else {
int count = map.get(bytes[i]);
map.put(bytes[i],count+1);
}
}
for (Map.Entry<Byte,Integer> entry:map.entrySet()){
Node node = new Node(entry.getKey(),entry.getValue());
nodes.add(node);
}
return nodes;
}
}