【Program】项目中遇到的问题

本文总结了基于Huffman编码的文件压缩项目中遇到的问题,包括压缩原理、配置文件内容、解压缩过程、二叉树保存、堆的使用、比较方法、类型重载、不安全函数的替换以及如何获取字节编码等关键点,详细探讨了解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基于 Huffman 树的文件压缩 项目中遇到的问题的汇总

1、压缩的分类?

  答:根据压缩之后的结果是否有损害,可分为有损压缩和无损压缩。解压缩的结果与源文件完全一样的是无损压缩,常用于对文本文件的压缩。解压缩的结果不能被完全还原是有损压缩,多用于图片、视频文件的压缩。

在这里插入图片描述


2、你这个项目的压缩原理什么?

  (1) 基于 Huffman 编码的文件压缩:

    ● 获取源文件中的每一个字节出现的次数;

    ● 根据字节出现的频率,构建 Huffman 树;

    ● 获取编码;

    ● 使用获取到的字节编码对源文件进行改写。

  (2) 压缩过程:

    第一步:统计源文件中每个字节出现的次数;

    第二步:根据统计的结果创建 Huffman 树;

      ① 根据所给的权值创建 n 个只有根节点的二叉树森林 F;

      ② 循环进行以下操作,直至 F 中剩余一颗二叉树为止。

        ● 从 F 中获取根节点的权值最小的两颗二叉树;

        ● 以这两棵树作为左右子树创建一颗新的二叉树,其根节点的权值为左右孩子节点中权值之和;

​        ● 将新的二叉树放回至 F 中。

    第三步:通过 Huffman 树来获取每个字节的编码;

    第四步:使用获取到的字节编码对源文件进行改写。

  (3) 配置文件中包含的信息有:

    ① 源文件的后缀;

    ② 字节频次信息的总行数;

    ③ 字节的频次信息;

    ④ 压缩数据。

(4) 解压缩过程:

  根据压缩数据对应的二进制比特流来遍历 Huffman 树:

    ① 一次获取每一个比特位;

    ② 如果该比特位为0,让 cur 往其左子树移动;

    ③ 如果该比特位为1,让 cur 往其右子树移动;

    ④ 直至 cur 走到叶子节点的位置,就成功解压缩成功一个字节。


3、用什么来来保存构建过程中的创建的这些二叉树呢?为什么选择使用堆?

  要保存这些二叉树,只需要保存二叉树根节点的地址即可。又因为要在二叉树森林中不断的选取根节点权值最小的两颗二叉树,进行构造新的二叉树,所以保存二叉树最好的结构的是堆,采用优先级队列,优先级队列就是采用堆来实现的。(优先级队列默认情况下是大堆,这里我们需要创建的是小堆,因此这里需要特别注意)


4、greater 比较方法, 不行 (使用地址创建了小堆,我们是需要权值来创建的小堆)


5、Comper 自定义比较方法(利用到仿函数)


6、在实例化 HuffmanTree 时,使用的是 ByteInfo 这样的结构体对象进行实例化,在编译时报出:未能从 ByteInfo 推导出模板参数这样的错误。

image-20210817170308692

  因为在模板函数创建的对象进行了加法操作和比较操作,如果是内置类型的对象就可以直接加或者比较,但如果是自定义类型的对象就必须进行重载,解决方法是对 + 和 > 进行重载。


7、在使用 fopen 时提示 This function or variable may be unsafe。

  解决方法一 :使用 fopen_s 函数代替 fopen 函数。

  解决方案二:在源文件的头部位置加入 #define _CRT_SECURE_NO_WARNINGS

  解决方案三: 打开项目 -> 属性 -> C/C++ -> 预处理器 -> 预处理器定义中添加 _CRT_SECURE_NO_WARNINGS 这个预定义。

  解决方案四:在 VS 的安装路径下找到newc++file.cpp 文件,在文件中添加 #define _CRT_SECURE_NO_WARNINGS 并保存,这样在每次新建一个文件,都会在首先自动生成 #define _CRT_SECURE_NO_WARNINGS 这个宏定义。


8、在创建 Huffman 树时需要剔除出现次数为 0 的字节


9、得到 Huffman 树以后如何得到每个字节的编码

  (1)在遍历的过程当中来获取(待完成)

  (2)遍历至叶子结点后,从叶子结点反向遍历,如果是左子树则 strCode + ‘0’,如果是右子树则 strCode + ‘1’,直至遍历到根节点,最后务必得逆置 reverse(strCode)。


10、string& strCode = fileByteInfo[cur->weight.ch].strCode;


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值