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;
        }
    }

最终结果

posted @ 2019-11-22 23:09  20182305孙铭泽  阅读(259)  评论(0编辑  收藏  举报