Huffman

20182305 Huffman編碼實踐的設計和實現過程

實踐內容

設有字符集: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)對編碼文件進行解碼,輸出一個解碼後的文件

什麼是哈夫曼樹

給定n個權值做爲n個葉子結點,構造一棵二叉樹,若帶權路徑長度達到最小,稱這樣的二叉樹爲最優二叉樹,也稱爲哈夫曼樹(Huffman Tree)。哈夫曼樹是帶權路徑長度最短的樹,權值較大的結點離根較近。

設計過程

  • 讀取文件中的字符並存入數組
File file = new File("E:\\JAVA\\111\\WindowsCode\\src\\Week10\\Huffman\\text1.txt");
        Readtxt read = new Readtxt();
        String temp = read.txtString(file);

        int[] num = read.getNumber();
        char[] chars = read.getChars();
        for(int i = 0;i<26;i++){
            System.out.print(chars[i]+":"+num[i]+"   ");
            list.add(new Node<String>(chars[i]+"",num[i]));
        }
        Collections.sort(list);
        System.out.println();
        HuffmanTree hufftree = new HuffmanTree();
        Node<String> root = hufftree.createTree(list);
  • 計算每一個字母出現的頻率,存入另外一數組
for(int i = 0;i<list2.size();i++)
        {
            if(list2.get(i).getData()!=null)
            {
                list3.add(list2.get(i).getData());
                list4.add(list2.get(i).getCode());
            }
        }

        for(int i = 0;i<list2.size();i++)
        {
            num2 += list2.get(i).getWeight();
        }

        for(int i = 1;i<list3.size();i++)
        {
            System.out.println(list3.get(i) + "出現的機率爲" + list2.get(i).getWeight()/num2 + "  ");
        }
        System.out.println();
  • 構造哈夫曼樹
public Node<T> createTree(List<Node<T>> nodes) 
    {
    
        while (nodes.size() > 1)
        {
            Collections.sort(nodes);

            Node<T> left = nodes.get(nodes.size() - 2);
            left.setCode(0 + "");
            Node<T> right = nodes.get(nodes.size() - 1);
            right.setCode(1 + "");
            Node<T> parent = new Node<T>(null, left.getWeight() + right.getWeight());
            parent.setLeft(left);
            parent.setRight(right);
            nodes.remove(left);
            nodes.remove(right);
            nodes.add(parent);
        }
        
        return nodes.get(0);
}
  • 文件編碼解碼並輸出
char[] chars = new char[]{'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',' '};
    int[] number = new int[]{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
    public String txtString(File file){
        StringBuilder result = new StringBuilder();
        try{
            BufferedReader br = new BufferedReader(new FileReader(file));
            String s = null;
            //一次讀一行
            while((s = br.readLine())!=null){
                result.append(System.lineSeparator()+s);
                num(s);
            }
            br.close();
        }catch(Exception e){
            e.printStackTrace();
        }
        return result.toString();
    }

    public void num(String string){
        for(int i = 0;i<27;i++){
            int temp = 0;
            for(int j = 0;j<string.length();j++){
                if(string.charAt(j) == chars[i])
                    temp++;
            }
            number[i] += temp;
        }
    }

最終結果

相關文章
相關標籤/搜索