package  com. atguigu. huffmancode; import  com. sun. org. glassfish. external. statistics. CountStatistic; 
import  com. sun. org. glassfish. external. statistics. StringStatistic; import  java. security. AlgorithmConstraints; 
import  java. util. *; 
public  class  HuffmanCode  { public  static  void  main ( String[ ]  args)  { String content= "i like like like java do you like a java" ; byte [ ]  contentBytes =  content. getBytes ( ) ; System. out. println ( contentBytes. length) ; byte [ ]  huffmanCodesBytes =  huffmanZip ( contentBytes) ; System. out. println ( "压缩后的结果" + Arrays. toString ( huffmanCodesBytes) + huffmanCodesBytes. length) ; byte [ ]  sourceBytes =  decode ( huffmanCodes,  huffmanCodesBytes) ; System. out. println ( new  String ( sourceBytes) ) ; 
} private  static  byte [ ]  decode ( Map< Byte, String> , byte [ ]  huffmanBytes) { StringBuilder stringBuilder =  new  StringBuilder ( ) ; for  ( int  i =  0 ;  i <  huffmanBytes. length;  i++ )  { byte  b =  huffmanBytes[ i] ; boolean  flag= ( i== huffmanBytes. length- 1 ) ; stringBuilder. append (  byteToBitString ( ! flag, b) ) ; } Map< String,  Byte> =  new  HashMap < > ( ) ; for ( Map. Entry< Byte,  String> : huffmanCodes. entrySet ( ) ) { map. put ( entry. getValue ( ) , entry. getKey ( ) ) ; } 
ArrayList< Byte> =  new  ArrayList < > ( ) ; for  ( int  i =  0 ;  i <  stringBuilder. length ( ) ; )  { int  count= 1 ; boolean  flag= true ; Byte b= null; while  ( flag) { String key =  stringBuilder. substring ( i,  i +  count) ; b= map. get ( key) ; if ( b== null) { count++ ; } else  { flag= false ; } } list. add ( b) ; i+= count; } byte [ ]  b =  new  byte [ list. size ( ) ] ; for  ( int  i =  0 ;  i <  b. length;  i++ )  { b[ i] = list. get ( i) ; } return  b; } private  static  String byteToBitString ( boolean  flag, byte  b) { int  temp= b; if ( flag) { temp|= 256 ; } String str =  Integer. toBinaryString ( temp) ; if ( flag) { return  str. substring ( str. length ( ) - 8 ) ; } else  { return  str; } } private  static  byte [ ]  huffmanZip ( byte [ ]  bytes) { List< Node> =  getNodes ( bytes) ; Node huffmanTreeRoot =  createHuffmanTree ( nodes) ; Map< Byte,  String> =  getCodes ( huffmanTreeRoot) ; byte [ ]  huffmanCodeBytes =  zip ( bytes,  huffmanCodes) ; return  huffmanCodeBytes; } private  static  byte [ ]  zip ( byte [ ]  bytes, Map< Byte, String> ) { StringBuilder stringBuilder =  new  StringBuilder ( ) ; for ( byte  b: bytes) { stringBuilder. append ( huffmanCodes. get ( b) ) ; } System. out. println ( "测试stringBuilder=" + stringBuilder. toString ( ) ) ; int  len; if ( stringBuilder. length ( ) % 8 == 0 ) { len= stringBuilder. length ( ) / 8 ; } else  { len= stringBuilder. length ( ) / 8 + 1 ; } byte [ ]  huffmanCodeBytes= new  byte [ len] ; int  index= 0 ; for  ( int  i =  0 ;  i <  stringBuilder. length ( ) ;  i+= 8 )  { String strByte; if ( i+ 8 > stringBuilder. length ( ) ) { strByte =  stringBuilder. substring ( i) ; } else  { strByte =  stringBuilder. substring ( i,  i +  8 ) ; } huffmanCodeBytes[ index] =  ( byte )  Integer. parseInt ( strByte, 2 ) ; index++ ; } return  huffmanCodeBytes; } static  Map< Byte, String> =  new  HashMap < Byte, String> ( ) ; static   StringBuilder stringBuilder= new  StringBuilder ( ) ; private  static  Map< Byte, String> getCodes ( Node root) { if ( root== null) { return  null; } getCodes ( root. left, "0" , stringBuilder) ; getCodes ( root. right, "1" , stringBuilder) ; return  huffmanCodes; } private  static  void  getCodes ( Node node, String code, StringBuilder stringBuilder) { StringBuilder stringBuilder2 =  new  StringBuilder ( stringBuilder) ; stringBuilder2. append ( code) ; if ( node!= null) { if ( node. data== null) { getCodes ( node. left, "0" , stringBuilder2) ; getCodes ( node. right, "1" , stringBuilder2) ; } else  { huffmanCodes. put ( node. data, stringBuilder2. toString ( ) ) ; } } } private  static  void  preOrder ( Node root) { if ( root!= null) { root. preOrder ( ) ; } else  { System. out. println ( "赫夫曼树为空" ) ; } } private  static  List< Node> getNodes ( byte [ ]  bytes) { ArrayList< Node> =  new  ArrayList < > ( ) ; HashMap< Byte,  Integer> =  new  HashMap < > ( ) ; for ( byte  b: bytes) { Integer count= counts. get ( b) ; if  ( count== null) { counts. put ( b, 1 ) ; } else  { counts. put ( b, count+ 1 ) ; } } for ( Map. Entry< Byte, Integer> : counts. entrySet ( ) ) { nodes. add ( new  Node ( entry. getKey ( ) , entry. getValue ( ) ) ) ; } return  nodes; } private  static  Node createHuffmanTree ( List< Node> ) { while  ( nodes. size ( ) > 1 ) { Collections. sort ( nodes) ; Node leftNode =  nodes. get ( 0 ) ; Node rightNode =  nodes. get ( 1 ) ; Node parent= new  Node ( null, leftNode. weight+ rightNode. weight) ; parent. left= leftNode; parent. right= rightNode; nodes. remove ( leftNode) ; nodes. remove ( rightNode) ; nodes. add ( parent) ; } return  nodes. get ( 0 ) ; } } 
class  Node  implements  Comparable < Node> { Byte data; int  weight; Node left; Node right; public  Node ( Byte data,  int  weight)  { this . data =  data; this . weight =  weight; } @Override public  int  compareTo ( Node o)  { return  this . weight- o. weight; } @Override public  String toString ( )  { return  "Node{"  + "data="  +  data + ", weight="  +  weight + '}' ; } public  void  preOrder ( ) { System. out. println ( this ) ; if ( this . left!= null) { this . left. preOrder ( ) ; } if  ( this . right!= null) { this . right. preOrder ( ) ; } } }