哈夫曼编码测试

哈夫曼编码实践

实践要求

  • 设有字符集: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)对编码文件进行解码,输出一个解码后的文件

哈夫曼编码

  • 一种编码方式,可以通过其算法来减小数据的存储空间,从而达到压缩文件的目的。
  • 主要原理:
    • 计算各个元素出现的频率也就是每个元素所占总元素的权重。根据权重的大小来进行后续的处理。
    • 哈夫曼树,通过树的数据结构来存储数据。哈夫曼树可以不为完全树,其度为2。特点在于,父结点总是给左子树为0,右子树为1。
    • 哈夫曼树的构造。对于所有元素,首先求出其所有的权重。对于这些森林,每次选出权重最小的两棵树,求其和,作为这两棵树的父结点。最终构造出哈夫曼树。根据其构造方法,我们可以发现,权重越大的结点,也就是其对应的元素越靠上,这样做的原因是因为权重越大,出现的愈加频繁,所以,以较短长度来替换出现次数最多的元素。从而使得存储空间得以减少。
    • 广度优先遍历,在得到各个结点的编码时,我们使用广度优先遍历来根据每层来增加一个0或1。不过,哈夫曼树是个树,也就是使用层序遍历来得到每个结点的编码。

代码实现

  • 在将对一个个的字符转换时,我想到计算机中每个元素都对应着一个ASCII码表值,所以,将其转化为ASCII值后,统计将变得较为便利。同时,为了存储数据方便,我使用了线性表来存储每一个结点。
  • 广度优先遍历,之前学习过这种遍历方法,也就是使用队列和列表来得到相应的结点,并在此时得出对应的哈夫曼码。先将父结点存入队列,再将其孩子结点存入队列,再将其弹出,弹出的进入列表。这样,这个列表就存储着所有的带着霍夫曼码的结点。
public Node createTreee(List<Node> nodes){

        while (nodes.size()>1){
            Collections.sort(nodes);
            Node left = nodes.get(nodes.size()-1);
            Node right = nodes.get(nodes.size()-2);
            Node parent = new Node(null,left.getWeight()+right.getWeight());
            parent.setLeft(left);
            parent.setRight(right);
            nodes.remove(nodes.size()-1);
            nodes.remove(nodes.size()-1);
            nodes.add(parent);

        }
        return nodes.get(0);
    }

    //广度遍历
    public  static List<Node> levelTraverse(Node root){
        List<Node> list = new ArrayList<Node>();
        Queue<Node> queue = new ArrayDeque<Node>();

        if (root != null) {
            queue.offer(root);
            root.getLeft().setCode(root.getCode() + "0");
            root.getRight().setCode(root.getCode() + "1");
        }

        while (!queue.isEmpty()) {
            list.add(queue.peek());
            Node node = queue.poll();
            if (node.getLeft() != null)
                node.getLeft().setCode(node.getCode() + "0");
            if (node.getRight() != null)
                node.getRight().setCode(node.getCode() + "1");

            if (node.getLeft() != null) {
                queue.offer(node.getLeft());
            }

            if (node.getRight() != null) {
                queue.offer(node.getRight());
            }
        }
        return list;
    }
    

结点实现类

 public Node(T data,double weight){
        this.data = data;
        this.weight = weight;
        this.code="";
    }

    public Node(T data, double weight, String code){
        this.data = data;
        this.weight = weight;
        this.code = code;

    }

运行结果



出现的问题

  • 出现了比较多的问题有类转化问题。
  • 因为使用了ASCII值,所以在使用诸如Long.parseLong()方法时,就会出现错误,因为char值不能使用String值进行强制类型转化,所以,在得到一个char值后,如果我们想使其变为String型时,最简单的方法就是给它加一个空字符串也就是“”,就可以了。
  • 同时,这次在读取文本时也出现了问题。往往最后一位的空格可能导致出错,因为其不可见,我们往往可能忽视这一细节。在写入时也可能导致出现这种错误。

原文地址:https://www.cnblogs.com/326477465-a/p/10105230.html

时间: 2024-11-13 09:42:40

哈夫曼编码测试的相关文章

20172327-哈夫曼编码测试

20172327-哈夫曼编码测试 哈夫曼编码与哈夫曼树 哈夫曼编码步骤 用Java实现哈夫曼编码 实验结果截图 码云链接 感悟 参考资料 原文地址:https://www.cnblogs.com/mrf1209/p/10111365.html

20182328哈夫曼编码测试

哈夫曼编码测试 班级: 1823 姓名:张景昊 学号:20182328 实验教师:王志强 实验日期:2019年11月22日 必修/选修: 必修 1.实验内容 设有字符集: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个英文字母的英文文件(可以不包含标点符号等),统计各个字符的概

基于python的二元霍夫曼编码译码详细设计

一.设计题目 对一幅BMP格式的灰度图像(个人证件照片)进行二元霍夫曼编码和译码 二.算法设计 (1)二元霍夫曼编码: ①:图像灰度处理: 利用python的PIL自带的灰度图像转换函数,首先将彩色图片转为灰度的bmp图像,此时每个像素点可以用单个像素点来表示. ②:二元霍夫曼编码: 程序流程图: 详细设计: 统计像素点频率,首先通过python自带的PIL库的图像像素点读取函数read()获取灰度图像的所有像素点,通过循环遍历每个像素点,将每个出现的像素点值以及其次数以键值对的形式放入到pyt

数据结构课程设计-哈夫曼编码译码

//******************************************** //程序功能:哈夫曼编码及译码 // //日期:2014年11月18 // //******************************************** #include<stdio.h> #include<stdlib.h> #include<string.h> #include <windows.h> #define MAX 128 //叶子节点

贪心算法-霍夫曼编码

霍夫曼编码是一种无损数据压缩算法.在计算机数据处理中,霍夫曼编码使用变长编码表对源符号(如文件中的一个字母)进行编码,其中变长编码表是通过一种评估来源符号出现机率的方法得到的,出现机率高的字母使用较短的编码,反之出现机率低的则使用较长的编码,这便使编码之后的字符串的平均长度.期望值降低,从而达到无损压缩数据的目的.例如,在英文中,e的出现机率最高,而z的出现概率则最低.当利用霍夫曼编码对一篇英文进行压缩时,e极有可能用一个比特来表示,而z则可能花去25个比特(不是26).用普通的表示方法时,每个

基于哈夫曼编码的压缩解压程序

这个程序是研一上学期的课程大作业.当时,跨专业的我只有一点 C 语言和数据结构基础,为此,我查阅了不少资料,再加上自己的思考和分析,实现后不断调试.测试和完善,耗时一周左右,在 2012/11/19 完成.虽然这是一个很小的程序,但却是我完成的第一个程序. 源码托管在 Github:点此打开链接 一.问题描述: 名称:基于哈夫曼编码的文件压缩解压 目的:利用哈夫曼编码压缩存储文件,节省空间 输入:任何格式的文件(压缩)或压缩文件(解压) 输出:压缩文件或解压后的原文件 功能:利用哈夫曼编码压缩解

哈夫曼编码(最优前缀码)

作为哈夫曼树的一个重要应用,我们来介绍哈夫曼编码.在我的上一篇博文<树之哈夫曼树>中已经介绍了建立哈夫曼树的过程,而由哈夫曼树求得的编码为最优前缀码.每个叶子表示的字符的编码,就是从根到叶子的路径上的标号依次相连所形成的编码,显然这就是该字符的最优前缀码.所谓前缀码是指,对字符集进行编码时,要求字符集中任一字符的编码都不是其它字符的编码的前缀,比如常见的等长编码就是前缀码.所谓最优前缀码是指,平均码长或文件总长最小的前缀编码称为最优的前缀码(这里的平均码长相当于码长的期望值). 我们知道,变长

java使用优先级队列实现哈夫曼编码

思路: 构建小根堆 根据小根堆实现哈夫曼树 根据哈夫曼树对数据进行编码 代码实现如下: /** * @Author: DaleyZou * @Description: 使用java实现一个哈夫曼编码的小程序 * @Date: Created in 19:45 2018-9-27 * @Modified By: */ public class HuffmanCode { private class Node implements Comparable<Node>{ char ch; // 字符

20182327 2019-2020 《程序设计与数据结构》哈夫曼编码测试报告

20182327 2019-2020 <程序设计与数据结构>哈夫曼编码测试报告 课程:<程序设计与数据结构> 班级: 1823 姓名:赵天昊 学号:20182327 实验教师:王志强 实验日期:2019年11月17日 必修/选修: 必修 教材中的哈夫曼树 1.在计算机数据处理中,哈夫曼编码使用变长编码表对源符号(如文件中的一个字母)进行编码,其中变长编码表是通过一种评估来源符号出现机率的方法得到的,出现机率高的字母使用较短的编码,反之出现机率低的则使用较长的编码,这便使编码之后的字