zoukankan      html  css  js  c++  java
  • 哈夫曼编码测试

    哈夫曼编码测试

    测试要求

    • 设有字符集: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)把实验结果截图上传到云班课

    设计思路

    1. 把字符从文件中取出来,这是以前学过的IO流实现的。
    2. 统计出现的字符及频率,将各个字符创建为叶子结点,频率为结点的权值,用链表保存这些叶子结点。
    3. 将所有带权值的结点按权值从小到大排列;
    4. 依次选取权值最小的结点放在树的底部,权值小的在左边(取出的结点相当于从这些结点的集合中剔除);
    5. 生成一个新节点作为这两个结点的父节点,且父节点的权值等于这两个结点权值之和,然后要把这个新结点放回我们需要构成树的结点中,继续进行排序;
    6. 重复上述2、3步骤,直至全部节点形成一棵树,此树便是哈夫曼树,最后生成的结点即为根节点。这样构成的哈夫曼树,所有的存储有信息的结点都在叶子结点上。
    7. 解码就是在二进制字符串中匹配字符哈夫曼编码,找到对应的字符不断输出。
    8. 理论上来说就是这么几步了。

    操作过程

    结点类

    • 我是在二叉树结点的基础上修改一下,主要是多定义了节点的哈夫曼编码、节点的权值。
    public class HNode {
    
        public String code = "";// 节点的哈夫曼编码
        public String data = "";// 节点的数据
        public int count;// 节点的权值
        public HNode left;
        public HNode right;
    
        public HNode(String data, int count) {
            this.data = data;
            this.count = count;
        }
    
        public HNode(int count, HNode lChild, HNode rChild) {
            this.count = count;
            this.left = lChild;
            this.right = rChild;
        }
    
        public HNode getLeft() {
            return left;
        }
    
        public void setLeft(HNode left) {
            this.left = left;
        }
    
        public HNode getRight() {
            return right;
        }
    
        public void setRight(HNode right) {
            this.right = right;
        }
    }
    

    哈夫曼树类

    • 肯定是先构建哈夫曼树了

    • 第一步肯定是要算出每个字符出现的次数得到其权值

    • 然后对得到的权值升序排序
    private void Sort(LinkedList<HNode> nodelist) {
            for (int i = 0; i < nodelist.size() - 1; i++) {
                for (int j = i + 1; j < nodelist.size(); j++) {
                    HNode temp;
                    if (nodelist.get(i).count > nodelist.get(j).count) {
                        temp = nodelist.get(i);
                        nodelist.set(i, nodelist.get(j));
                        nodelist.set(j, temp);
                    }
                }
            }
        }`
    
    • 之后取出权值最小的两个节点,生成一个新的父节点,删除权值最小的两个节点,将父节点存放到列表中,并不断重复,直到得到根节点。

    • 最后就是通过遍历得到字符的哈夫曼编码

    • 在然后就是解码了

    • 需要解码的二进制字符串,匹配字符哈夫曼编码,找到对应的字符

    测试类

    • 先IO流得到字符串
    File file = new File("C:\Users\lenovo\IdeaProjects\why20172321\src\week10\哈夫曼树解码\hfm.txt");
            Reader reader = new FileReader(file);
            BufferedReader bufferedReader = new BufferedReader(reader);
            String data = bufferedReader.readLine();
    
    • 输出一下每个数的概率和对应的哈夫曼编码。
    • 得到编码结果并输入文件,然后读取文件进行解码,并将解码内容输出。

    测试结果

    码云代码

  • 相关阅读:
    使用UOS微信桌面版协议登录,wechaty免费版web协议又可以用了
    angular之$watch方法详解
    webpack配置这一篇就够
    select设置disable后ie修改默认字体颜色暂时解决
    201901251946
    new year
    test
    mysql密码忘记解决方法
    bianmayujianmatest
    jinzhizhuanhuan
  • 原文地址:https://www.cnblogs.com/N-idhogg/p/10105547.html
Copyright © 2011-2022 走看看