設有字符集: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
HuffmanNode設計this
public class Node { public String code = ""; public String data = ""; public int count; public Node lChild; public Node rChild; public Node() { } public Node(String data, int count) { this.data = data; this.count = count; } public Node(int count, Node lChild, Node rChild) { this.count = count; this.lChild = lChild; this.rChild = rChild; } public Node( String data, int count, Node lChild, Node rChild) { this.data = data; this.count = count; this.lChild = lChild; this.rChild = rChild; } }
哈夫曼樹構造分爲如下幾步:編碼
public void creatHfmTree(String str) { this.str = str; NodeList = new LinkedList<HNode>(); charList = new LinkedList<CharData>(); // 1.統計字符串中字符以及字符的出現次數 // 以CharData類來統計出現的字符和個數 getCharNum(str); // 2.根據第一步的結構,建立節點 creatNodes(); // 3.對節點權值升序排序 Sort(NodeList); // 4.取出權值最小的兩個節點,生成一個新的父節點 // 5.刪除權值最小的兩個節點,將父節點存放到列表中 creatTree(); // 6.重複第四五步,就是那個while循環 // 7.將最後的一個節點賦給根節點 root = NodeList.get(0); }
編解碼實現:設計
private String hfmCodeStr = "";// 哈夫曼編碼鏈接成的字符串 /** * 編碼 * @param str * @return */ public String toHufmCode(String str) { for (int i = 0; i < str.length(); i++) { String c = str.charAt(i) + ""; search(root, c); } return hfmCodeStr; } /** * * @param root 哈夫曼樹根節點 * @param c 須要生成編碼的字符 */ 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); } } // 保存解碼的字符串 String result=""; boolean target = false; // 解碼標記 /** * 解碼 * @param codeStr * @return */ 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); // 解碼 // 每解碼一個字符,start向後移 if(target){ start = end; } end++; } return result; } /** * 匹配字符哈夫曼編碼,找到對應的字符 * @param root 哈夫曼樹根節點 * @param code 須要解碼的二進制字符串 */ private void matchCode(HNode root, String code){ if (root.lChild == null && root.rChild == null) { if (code.equals(root.code)) { result += root.data; // 找到對應的字符,拼接到解碼字符穿後 target = true; // 標誌置爲true } } if (root.lChild != null) { matchCode(root.lChild, code); } if (root.rChild != null) { matchCode(root.rChild, code); } } }
碼雲連接code