哈夫曼編碼譯碼器
僅供學習和參考,這份代碼的算法和文件操作都參考了許多文章。
僅供學習和參考,這份代碼的算法和文件操作都參考了許多文章。
僅供學習和參考,這份代碼的算法和文件操作都參考了許多文章。
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;
}
}
}
}