1. 程式人生 > 實用技巧 >20192312吳欣欣 哈夫曼編碼實踐 實驗報告

20192312吳欣欣 哈夫曼編碼實踐 實驗報告

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等知識,同時又重新回顧了排序的相關內容。