設有字符集: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)把實驗結果截圖上傳到雲班課node
//讀取文件中出現的字符,並記錄出現次數 File file = new File("C:\\Users\\12257\\IdeaProjects\\20172310qx\\src\\Huffman\\text"); if (!file.exists()) { throw new Exception("文件不存在"); } BufferedReader fin = new BufferedReader(new FileReader(file)); String line; //map儲存數據的形式是一個key和一個value對應 Map<Character, Integer> counter = new HashMap<Character, Integer>(); int total=0; //讀取一個文本行 while ((line = fin.readLine()) != null) { int len = line.length(); for (int i = 0; i < len; i++) { char c = line.charAt(i); if (( (c >= 'a' && c <= 'z'&& c == ' '))) { continue; } // 若是此映射包含指定鍵的映射關係,則返回 true if (counter.containsKey(c)) { counter.put(c, counter.get(c) + 1); } else { counter.put(c, 1); } } } fin.close();//文件讀取結束 //經過Map.keySet遍歷key和value: Iterator<Character> pl = counter.keySet().iterator(); int a = 0; while (pl.hasNext()) { char key = pl.next(); int count = counter.get(key); // System.out.println(key + " --- " + count); a++; }
private T data;//數據 public T getData() { return data; } public void setData(T data) { this.data = data; } protected double weight;//權重 protected Node<T> leftChild; protected Node<T> rightChild; public String codeNumber; public Node(T data , double weight) { this.data = data; this.weight = weight; this.codeNumber = ""; } public String getCodeNumber() { return codeNumber; } public void setCodeNumber(String codeNumber) { this.codeNumber = codeNumber; } public double getWeight() { return weight; } public void setWeight(double weight) { this.weight = weight; } public String toString() { return "Node[data=" + data + ", weight=" + weight + ",codeNumber = "+codeNumber+"]"; } }
public static Node createTree(List<Node> nodes) { // 只要nodes數組中還有2個以上的節點 while (nodes.size() > 1) { quickSort(nodes); //獲取權值最小的兩個節點 Node left = nodes.get(nodes.size()-1); left.setCodeNumber(0+""); Node right = nodes.get(nodes.size()-2); right.setCodeNumber(1+""); //生成新節點,新節點的權值爲兩個子節點的權值之和 Node parent = new Node(null, left.weight + right.weight); //讓新節點做爲兩個權值最小節點的父節點 parent.leftChild = left; parent.rightChild = right; //刪除權值最小的兩個節點 nodes.remove(nodes.size()-1); nodes.remove(nodes.size()-1); //將新節點加入到集合中 nodes.add(parent); } return nodes.get(0); }
如今已經對每一個字符都進行了對應的編碼,只要一一對應就能夠相應的編碼解碼。git
double num2 = 0; for (int i = 0; i < list2.size(); i++) { num2 += list2.get(i).getWeight(); } for (int i = 0; i < list3.size(); i++) { System.out.println("字符爲:"+list3.get(i) + "機率爲:" + list2.get(i).getWeight() / num2 + " "); } System.out.println(); String temp2 = "", temp3 = ""; for (int i = 0; i < list4.size(); i++) { System.out.println(list3.get(i) + "的編碼爲" + list4.get(i) + " "); } System.out.println();
List<String> list5 = new ArrayList<String>(); System.out.println(); for (int i = 0; i < result.length(); i++) { for (int j = 0; j < list3.size(); j++) { if (result.charAt(i) == list3.get(j).charAt(0)) result1 += list4.get(j); } } System.out.println("編碼後爲:" + result1);