哈夫曼編碼

20172319 2018.12.07

哈夫曼編碼

課程名稱:《程序設計與數據結構》  
學生班級:1723班  
學生姓名:唐才銘  
學生學號:20172319 
實驗教師:王志強老師
課程助教:張師瑜學姐、張之睿學長
實驗時間:2018年12月07日
必修/選修:必修

目錄


實踐內容

設有字符集: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)把實驗結果截圖上傳到雲班課
滿分:6分。
酌情打分。html

返回目錄java


實踐要求

  1. 完成藍墨雲上哈夫曼編碼測試相關的活動,及時提交代碼運行截圖和碼雲Git連接,截圖要有學號水印,不然會扣分。
  2. 完成實驗、撰寫實驗報告,實驗報告以博客方式發表在博客園,注意實驗報告重點是運行結果,遇到的問題(工具查找,安裝,使用,程序的編輯,調試,運行等)、解決辦法(空洞的方法如「查網絡」、「問同窗」、「看書」等一概得0分)以及分析(從中能夠獲得什麼啓示,有什麼收穫,教訓等)。報告能夠參考範飛龍老師的指導
  3. 嚴禁抄襲,有該行爲者實驗成績歸零,並附加其餘懲罰措施。

返回目錄node


實踐步驟

設有字符集: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)把實驗結果截圖上傳到雲班課
滿分:6分。
酌情打分。git

前期準備:

  1. 預先下載安裝好IDEA 。

需求分析:

  • 須要瞭解、理解哈夫曼編碼的相關知識

返回目錄網絡


代碼實現及解釋

(1)準備一個包含26個英文字母的英文文件(能夠不包含標點符號等),統計各個字符的機率數據結構

  • 在src目錄下右鍵,新建文件,輸入文件名,文本文件,以後將本身所需內容放入便可。
  • 讀取文件內容:
File fromFile = new File("English-text");
        // 建立字符輸入流
        Reader reader = null;
        String data = "";

        List temp = new LinkedList();
        try {
            reader = new FileReader(fromFile);
            // 循環讀取(打印)
            int content = reader.read();
            while (content != -1) {
                System.out.print((char) content);
                temp.add(content);
                data += (char) content;
                content = reader.read();
            }
            System.out.println();
  • 文件中可能有些字符如:\n \r之類的,能夠使用replace方法將其替換成「」字符。
  • 實現截圖以下:
    工具

  • 統計各個字符出現的機率:測試

public static void printStr(String str, int[] Probabilities, String[] Data ) {
        if (str == null || "".equals(str)) {
            System.out.println("字符串不能爲空!");
            return;
        }
        Map<String, Integer> pMap = new HashMap<String, Integer>();
        String[] split = str.split("");
        for (int i = 0; i < split.length; i++) {
            if (!"".equals(split[i]) && pMap.containsKey(split[i])) {
                pMap.put(split[i], pMap.get(split[i]) + 1);
            } else if (!"".equals(split[i])) {
                pMap.put(split[i], 1);
            }
        }
        Set<String> keySet = pMap.keySet();
        int total = 0;
        int i = 0;
        for (String string : keySet) {
            total += pMap.get(string);
        }
        for (String string : keySet) {
            Probabilities[i] =pMap.get(string)  ;
            Data[i] = string;
            System.out.println(string + "出現的機率:" + "分數: " + pMap.get(string) + "/" + total
                    + "\t" + "小數:" + (double) pMap.get(string) / total);
            i++;
        }
    }
  • 實現截圖以下:

(2)構造哈夫曼樹編碼

public static <T> HuffmanNode<T> CreatTree(List<HuffmanNode<T>> HuffmanNode) {
            while (HuffmanNode.size() > 1) {
                Collections.sort(HuffmanNode);
                HuffmanNode<T> left = HuffmanNode.get(HuffmanNode.size() - 1);
                HuffmanNode<T> right = HuffmanNode.get(HuffmanNode.size() - 2);
                HuffmanNode<T> parent = new HuffmanNode<T>(null,left.getWeight()
                        + right.getWeight());
                parent.setLeftChild(left);
                parent.setRightChild(right);
                HuffmanNode.remove(left);
                HuffmanNode.remove(right);
                HuffmanNode.add(parent);
            }
            return HuffmanNode.get(0);
        }

        public static <T> List<HuffmanNode<T>> breadth(HuffmanNode<T> Root) {
            List<HuffmanNode<T>> list = new ArrayList<HuffmanNode<T>>();
            Queue<HuffmanNode<T>> queue = new ArrayDeque<HuffmanNode<T>>();

            if (Root != null) {
                queue.offer(Root);
            }

            while (!queue.isEmpty()) {
                list.add(queue.peek());
                HuffmanNode<T> node = queue.poll();

                if (node.getLeftChild() != null) {
                    queue.offer(node.getLeftChild());
                }

                if (node.getRightChild() != null) {
                    queue.offer(node.getRightChild());
                }
            }
            return list;
        }
    }
  • 實現截圖以下:

(3)對英文文件進行編碼,輸出一個編碼後的文件設計

public String toHufmCode(String str) {

            for (int i = 0; i < str.length(); i++) {
                String c = str.charAt(i) + "";
                search(root, c);
            }

            return hfmCodeStr;
        }


        private void search(HNode root, String c) {
            if (root.lChild == null && root.rChild == null) {
                if (c.equals(root.data)) {
                    hfmCodeStr += root.code;
                }
            }
            if (root.lChild != null) {
                search(root.lChild, c);
            }
            if (root.rChild != null) {
                search(root.rChild, c);
            }
        }
  • 實現截圖以下:

(4)對編碼文件進行解碼,輸出一個解碼後的文件

public String CodeToString(String codeStr) {

            int start = 0;
            int end = 1;

            while(end <= codeStr.length()){
                target = false;
                String s = codeStr.substring(start, end);
                matchCode(root, s);
                if(target){
                    start = end;
                }
                end++;
            }

            return result;
        }

        private void matchCode(HNode root, String code){
            if (root.lChild == null && root.rChild == null) {
                if (code.equals(root.code)) {
                    result += root.data;
                    target = true;
                }
            }
            if (root.lChild != null) {
                matchCode(root.lChild, code);
            }
            if (root.rChild != null) {
                matchCode(root.rChild, code);
            }

        }
    }
  • 實現截圖以下:

返回目錄


測試過程及遇到的問題

  • 問題1: 無任何記錄。
  • 解決:

返回目錄


分析總結

返回目錄


代碼託管

返回目錄


參考資料

Intellj IDEA 簡易教程

返回目錄

相關文章
相關標籤/搜索