哈夫曼编码译码器
1. 选择需要进行编码的文件
2.建立哈夫曼树
3.建立密码本并对文件编码
4.选择需要进行解码的文件并解码
5.按位压缩方式对文件进行压缩
6.解压压缩文件为编码文件
一共三个类,Huffman类也是程序的入口
下面的代码中注释将对代码有详细的讲解
public class Node < T> {
int key;
T charData;
Node leftChild;
Node rightChild;
}
public class Tree implements Comparable < Tree> {
private Node root;
public Node getRoot ( ) {
return root;
}
public void setRoot ( Node root) {
this . root = root;
}
public void inDisplay ( Node node) {
if ( node!= null) {
inDisplay ( node. leftChild) ;
System. out. println ( node. key+ ":" + node. charData) ;
inDisplay ( node. rightChild) ;
}
}
@Override
public int compareTo ( Tree o) {
return 0 ;
}
}
到这为止都没什么好说的,没涉及到什么算法,也没有复杂的操作,接下来是代码的核心(带注释)
package Misson6_bing;
import 实验3. KeyInput;
import java. awt. event. KeyEvent;
import java. io. *;
import java. util. HashMap;
import java. util. Map;
import java. util. PriorityQueue;
public class Huffman {
private Map< Character, Integer> map= new HashMap < > ( ) ;
private Map< Character, String> ce= new HashMap < > ( ) ;
private PriorityQueue< Tree> trees= new PriorityQueue < > ( ) ;
private String source;
public void init ( String source) {
this . source= source;
char [ ] chars= source. toCharArray ( ) ;
for ( char c : chars) {
if ( ! map. containsKey ( c) ) {
map. put ( c, 1 ) ;
} else {
map. put ( c, map. get ( c) + 1 ) ;
}
}
afterInit ( ) ;
}
private void afterInit ( ) {
map. forEach ( ( c, count) - > {
Node< Character> node= new Node < > ( ) ;
node. key= count;
node. charData= c;
Tree tree= new Tree ( ) ;
tree. setRoot ( node) ;
trees. add ( tree) ;
} ) ;
}
public void build ( ) {
while ( this . trees. size ( ) > 1 ) {
Tree left= this . trees. poll ( ) ;
Tree right= this . trees. poll ( ) ;
Node node= new Node ( ) ;
node. key= left. getRoot ( ) . key+ right. getRoot ( ) . key;
node. leftChild= left. getRoot ( ) ;
node. rightChild= right. getRoot ( ) ;
left. setRoot ( node) ;
this . trees. add ( left) ;
}
}
public void encoding ( ) {
Tree tree= this . trees. peek ( ) ;
this . encoding ( tree. getRoot ( ) , "" ) ;
ce. forEach ( ( k, v) - > {
if ( v. length ( ) < 8 ) {
String s1= String. format ( "%08d" , Integer. valueOf ( v) ) ;
ce. put ( k, s1) ;
}
} ) ;
}
public String encodingResult ( ) {
StringBuilder sb= new StringBuilder ( ) ;
char [ ] chars= source. toCharArray ( ) ;
for ( char c : chars) {
sb. append ( ce. get ( c) ) ;
}
return sb. toString ( ) ;
}
private void encoding ( Node< Character> node, String encoding) {
if ( node!= null) {
if ( node. leftChild== null && node. rightChild== null) {
ce. put ( node. charData, encoding) ;
}
encoding ( node. leftChild, encoding+ "0" ) ;
encoding ( node. rightChild, encoding+ "1" ) ;
}
}
public void displayTree ( ) {
Tree tree= this . trees. peek ( ) ;
tree. inDisplay ( tree. getRoot ( ) ) ;
}
public void displayEncodeing ( ) {
ce. forEach ( ( k, v) - > {
System. out. println ( k+ ":" + v) ;
} ) ;
}
public String decoding ( String encodeStr, Map< Character, String> encodeMap) throws IOException {
StringBuilder decodeStr = new StringBuilder ( ) ;
while ( encodeStr. length ( ) > 1 ) {
for ( Map. Entry< Character, String> e: encodeMap. entrySet ( ) ) {
String charEncodeStr = e. getValue ( ) ;
if ( encodeStr. startsWith ( charEncodeStr) ) {
decodeStr. append ( e. getKey ( ) ) ;
encodeStr = encodeStr. substring ( charEncodeStr. length ( ) ) ;
break ;
}
}
}
return decodeStr. toString ( ) ;
}
public static boolean creatFile ( String filePath) throws IOException {
boolean flag= false ;
File newF= new File ( filePath) ;
if ( ! newF. exists ( ) ) {
try {
newF. createNewFile ( ) ;
}
catch ( IOException e) {
e. printStackTrace ( ) ;
}
flag= true ;
}
return flag;
}
public static String readTextFile_FR ( String filePath) throws IOException {
String thisLine= null;
String result= "" ;
creatFile ( filePath) ;
File file= new File ( filePath) ;
if ( file. exists ( ) && file. isFile ( ) ) {
try {
BufferedReader br= new BufferedReader ( new FileReader ( filePath) ) ;
while ( ( thisLine= br. readLine ( ) ) != null) {
result+= thisLine+ "\n" ;
}
br. close ( ) ;
}
catch ( Exception e) {
e. printStackTrace ( ) ;
}
}
return result;
}
public static boolean write_byte_file ( String content, String filePath, boolean append) {
boolean flag= false ;
char [ ] chars= content. toCharArray ( ) ;
byte [ ] bytes = new byte [ chars. length] ;
int i= 0 ;
for ( char c: chars) {
if ( c== '\n' ) {
break ;
}
int t= Integer. parseInt ( String. valueOf ( c) ) ;
bytes[ i] = ( byte ) t;
i++ ;
}
File thisFile= new File ( filePath) ;
try {
if ( ! thisFile. exists ( ) ) {
thisFile. createNewFile ( ) ;
}
FileOutputStream fos = new FileOutputStream ( filePath) ;
fos. write ( bytes) ;
fos. close ( ) ;
} catch ( IOException e) {
e. printStackTrace ( ) ;
}
flag= true ;
return flag;
}
public static byte [ ] read_byte_file ( String filePath) throws IOException {
creatFile ( filePath) ;
File file= new File ( filePath) ;
try {
FileInputStream in = new FileInputStream ( new File ( filePath) ) ;
byte [ ] data= new byte [ in. available ( ) ] ;
in. read ( data) ;
in. close ( ) ;
return data;
} catch ( Exception e) {
e. printStackTrace ( ) ;
return null;
}
}
public static boolean compressFile_CF ( String filePath_r, String filePath_w, boolean append) throws IOException {
boolean flag= false ;
creatFile ( filePath_w) ;
String content= readTextFile_FR ( filePath_r) ;
StringBuilder content_cod= new StringBuilder ( ) ;
int j= 0 ;
for ( int i= 0 ; i< content. length ( ) ; i+= 8 ) {
if ( ( 8 * ( j+ 1 ) - 1 ) > content. length ( ) ) {
break ;
}
int keys= Integer. parseInt ( content. substring ( 8 * j, ( 8 * ( j+ 1 ) - 1 ) ) , 2 ) ;
content_cod. append ( keys) ;
j++ ;
}
System. out. println ( content_cod) ;
write_byte_file ( content_cod. toString ( ) , filePath_w, false ) ;
flag= true ;
System. out. println ( "压缩比 " + content. length ( ) + ":" + content_cod. length ( ) ) ;
return flag;
}
public static boolean decompressFile_DF ( String filePath_com) throws IOException {
boolean flag= false ;
byte [ ] bytes= read_byte_file ( filePath_com) ;
StringBuilder content_decom= new StringBuilder ( ) ;
StringBuilder content_com= new StringBuilder ( ) ;
for ( byte b: bytes) {
int t= ( int ) b;
content_com. append ( String. valueOf ( t) ) ;
}
char [ ] chars= content_com. toString ( ) . toCharArray ( ) ;
for ( char c: chars) {
if ( c== '\n' ) {
break ;
}
int temp= Integer. parseInt ( String. valueOf ( c) ) ;
String s1= String. format ( "%08d" , Integer. valueOf ( Integer. toBinaryString ( temp) ) . intValue ( ) ) ;
content_decom. append ( s1) ;
}
writeTextFile_FW ( content_decom. toString ( ) , filePath_com, false ) ;
flag= true ;
return flag;
}
public static boolean writeTextFile_FW ( String content, String filePath, boolean append) {
boolean flag= false ;
File thisFile= new File ( filePath) ;
try {
if ( ! thisFile. exists ( ) ) {
thisFile. createNewFile ( ) ;
}
BufferedWriter bw= new BufferedWriter ( new FileWriter ( filePath, append) ) ;
bw. write ( content) ;
bw. close ( ) ;
} catch ( IOException e) {
e. printStackTrace ( ) ;
}
flag= true ;
return flag;
}
public static void main ( String[ ] args) throws IOException {
Huffman huffman= new Huffman ( ) ;
int fun= - 1 ;
while ( fun!= 0 ) {
System. out. println ( "***************************************" ) ;
System. out. println ( "* 1.选择/创建需要进行编码的文件 *" ) ;
System. out. println ( "* 2.建立哈夫曼树 *" ) ;
System. out. println ( "* 3.建立密码本并对文件编码 *" ) ;
System. out. println ( "* 4.选择需要解码的文件并解码 *" ) ;
System. out. println ( "* 5.按位压缩方式对文件进行压缩 *" ) ;
System. out. println ( "* 6.解压压缩文件 *" ) ;
System. out. println ( "*************************************\n" ) ;
fun= KeyInput. readInt ( ) ;
String compress_file= "D:\\\\数据结构\\\\文件存放处\\\\The compress_code.cod" ;
switch ( fun) {
default :
System. out. println ( "No such function found,try again!" ) ;
System. in. read ( ) ;
case 1 :
System. out. println ( "1.D:\\\\数据结构\\\\文件存放处\\\\Test1.txt" ) ;
System. in. read ( ) ;
creatFile ( "D:\\\\数据结构\\\\文件存放处\\\\Test1.txt" ) ;
System. out. println ( "选择功能\n1.向文件中写入内容\n2.直接读取" ) ;
int fun1= KeyInput. readInt ( ) ;
if ( fun1== 1 ) {
boolean append= true ;
System. out. println ( "1.选择追加\n2.选择覆盖" ) ;
int ap= KeyInput. readInt ( ) ;
if ( ap== 2 ) {
append= false ;
}
System. out. println ( "请输入你要写入文件的字符串" ) ;
String s1= KeyInput. readString ( ) ;
writeTextFile_FW ( s1, "D:\\\\数据结构\\\\文件存放处\\\\Test1.txt" , append) ;
}
else {
String s= readTextFile_FR ( "D:\\\\数据结构\\\\文件存放处\\\\Test1.txt" ) ;
System. out. println ( s) ;
}
break ;
case 2 :
String source= readTextFile_FR ( "D:\\\\数据结构\\\\文件存放处\\\\Test1.txt" ) ;
System. out. println ( "文件内容为: " + source) ;
huffman. init ( source) ;
huffman. build ( ) ;
huffman. displayTree ( ) ;
break ;
case 3 :
huffman. encoding ( ) ;
huffman. displayEncodeing ( ) ;
System. out. println ( huffman. encodingResult ( ) ) ;
try {
writeTextFile_FW ( huffman. encodingResult ( ) , "D:\\\\数据结构\\\\文件存放处\\\\The code.cod" , false ) ;
}
catch ( Exception e) {
e. printStackTrace ( ) ;
}
break ;
case 4 :
String s1= null;
s1= readTextFile_FR ( "D:\\\\数据结构\\\\文件存放处\\\\The code.cod" ) ;
System. out. println ( s1) ;
String decode= "" ;
decode= huffman. decoding ( s1, huffman. ce) ;
System. out. println ( decode) ;
break ;
case 5 :
System. out. println ( "开始压缩..." ) ;
long start= System. currentTimeMillis ( ) ;
compressFile_CF ( "D:\\\\数据结构\\\\文件存放处\\\\The code.cod" , compress_file, false ) ;
System. out. println ( "压缩结束...用时:" + ( System. currentTimeMillis ( ) - start) ) ;
break ;
case 6 :
System. out. println ( "开始解压..." ) ;
long start1= System. currentTimeMillis ( ) ;
decompressFile_DF ( compress_file) ;
System. out. println ( "解压结束...用时:" + ( System. currentTimeMillis ( ) - start1) ) ;
break ;
case 0 :
break ;
}
}
}
}