20192312吳欣欣 哈夫曼編碼實踐 實驗報告
阿新 • • 發佈:2020-12-13
20192312 2020-2021-1 實驗七 《查詢與排序》實驗報告
課程:《程式設計與資料結構》
班級: 1923
姓名: 吳欣欣
學號:20192312
實驗教師:王志強
實驗日期:2020年12月10日
必修/選修: 必修
1.實驗內容
設有字符集:S={a,b,c,d,e,f,g,h,i,j,k,l,m,n.o.p.q,r,s,t,u,v,w,x,y,z}。
給定一個包含26個英文字母的檔案,統計每個字元出現的概率,根據計算的概率構造一顆哈夫曼樹。
並完成對英文檔案的編碼和解碼。
要求:
(1)準備一個包含26個英文字母的英文檔案(可以不包含標點符號等),統計各個字元的概率
(2)構造哈夫曼樹
(3)對英文檔案進行編碼,輸出一個編碼後的檔案
(4)對編碼檔案進行解碼,輸出一個解碼後的檔案
(5)撰寫部落格記錄實驗的設計和實現過程,並將原始碼傳到碼雲
(6)把實驗結果截圖上傳到雲班課
2.實驗過程及結果
1.編寫結點類,除葉子結點,既字母外,其他結點權重為子結點權重之和。同時實現對節點的編碼。
package week14; public class HaffNode<T>{ char data; int weight; HaffNode father,leftChild,rightChild; public HaffNode(char s){ this.data=s; weight=0; father=null; leftChild=null; rightChild=null; } public HaffNode(HaffNode a,HaffNode b){ this.data=' '; weight=a.weight+b.weight; father=null; leftChild=a; rightChild=b; a.father=this; b.father=this; } public String code(HaffNode root){//逆向編碼 String a=""; if(father!=null){ if(this==father.leftChild)a+="0"+father.code(root); else a+="1"+father.code(root); } return a; } public String recode(HaffNode root){ String a=code(root); String b=""; for(int i=a.length()-1;i>=0;i--){ b+=a.charAt(i); } return b; } }
2.編寫哈夫曼樹,排序後連線權重最小的兩結點並插入新結點再排序。
package week14; import java.util.Arrays; public class HaffTree <T>{ HaffNode root; public HaffTree(){ root=null; } public HaffTree(HaffNode [] node){ while(node.length>1){ node=sort(node); HaffNode current=new HaffNode(node[0],node[1]); node[1]=current; node= Arrays.copyOfRange(node,1,node.length); } root=node[0]; } public HaffNode[] sort(HaffNode[] node){ for(int gap=node.length/2;gap>0;gap/=2){ for(int i=gap;i<node.length;i++){ int j=i; while (j-gap>=0&&node[j].weight<node[j-gap].weight){ swap(node,j,j-gap); j-=gap; } } } return node; } public void swap(HaffNode [] node,int a,int b){ HaffNode temp; temp=node[a]; node[a]=node[b]; node[b]=temp; } public String decode(String s){//解碼 String str=""; int i=0; HaffNode current=root; while(i<s.length()) { while (current.leftChild != null) { if (s.charAt(i)=='0') current = current.leftChild; else current = current.rightChild; i++; } str+=current.data; current=root; } return str; } }
3.測試程式碼
package week14;
import java.io.*;
import java.util.Arrays;
public class test {
public static void main(String[] args) throws IOException {
String s = "",s1="";
char a = 'a';
HaffNode[] node = new HaffNode[26];
for (int i = 0; i < 26; i++) {
node[i] = new HaffNode(a);
a++;
}
File file= new File("C:\\Users\\86139\\Desktop", "file1.txt"); //建立檔案物件
File file1=new File("C:\\Users\\86139\\Desktop","file2.txt");
File file2=new File("C:\\Users\\86139\\Desktop","file3.txt");
if(!file1.exists()) { file1.createNewFile(); }
if(!file2.exists()) { file2.createNewFile(); }
FileReader fr1 = new FileReader(file);
FileReader fr2 = new FileReader(file1);
s=Read(fr1);
fr1.close();
for (int i = 0; i < s.length(); i++) {
int num = s.charAt(i) - 'a';
node[num].weight++;
}
HaffNode[] node1 = Arrays.copyOf(node, node.length);
FileWriter fw1=new FileWriter(file1);
FileWriter fw2=new FileWriter(file2);
String code = "";
HaffTree tree = new HaffTree(node1);
for (int i = 0; i < s.length(); i++) {
int num = s.charAt(i) - 'a';
code += node[num].recode(tree.root);
}
fw1.write(code);
fw1.close();
s=Read(fr2);
fr2.close();
fw2.write(tree.decode(s));
fw2.close();
}
public static String Read(FileReader fr) throws IOException {
String s="";
char[] data = new char[26];
int length =0;
while ((length = fr.read(data)) > 0) {
s+= new String(data, 0, length);
}
return s;
}
}
3.心得體會
鞏固了File,以及FileReader等知識,同時又重新回顧了排序的相關內容。