每天一道算法练习题--Day16 && 第一章 --算法专题 --- ----------哈夫曼编码和游程编码

2023-10-30

Huffman encode(哈夫曼编码)

Huffman 编码的基本思想就是用短的编码表示出现频率高的字符,用长的编码来表示出现频率低的字符,这使得编码之后的字符串的平均长度、长度的期望值降低,从而实现压缩的目的。 因此 Huffman 编码被广泛地应用于无损压缩领域。 可以看出, huffman 编码是一种可变编码,而不是固定长度编码。

Huffman 编码的过程包含两个主要部分:

  • 根据输入字符构建 Huffman 树
  • 遍历 Huffman 树,并将树的节点分配给字符

上面提到了他的基本原理就是用短的编码表示出现频率高的字符,用长的编码来表示出现频率低的字符,因此首先要做的就是统计字符的出现频率,然后根据统计的频率来构建 Huffman 树(又叫最优二叉树)。

如图,huffman 树以一颗二叉树。 其中节点的左子节点路径用 0 表示,右子节点用 1 表示,节点的值表示的是其权重,权重越大深度越小。深度表示的其实就是编码的长度。通常我们使用字符出现的频率作为权重。真正执行编码的时候,类似字典树,节点不用来编码,节点的路径用来编码.

如果计算机使用三进制,而不是二进制,那么 huffman 树就应该是一个三叉树。

实例

比如我们对一个字符串的频率统计的结果如下:
在这里插入图片描述

  • 将每个元素构造成一个节点,即只有一个元素的树。并构建一个最小堆,包含所有的节点,该算法用了最小堆来作为优先队列。
  • 选取两个权值最小的节点,并添加一个权值为 5+9=14 的节点,作为他们的父节点。并更新最小堆,现在最小堆包含 5 个节点,其中 4 个树还是原来的节点,权值为 5 和 9 的节点合并为一个。

结果是这样的:
在这里插入图片描述

run-length encode(游程编码)

游程编码是一种比较简单的压缩算法,其基本思想是将重复且连续出现多次的字符使用(连续出现次数,某个字符)来描述。

在这里插入图片描述

5A 表示这个地方有 5 个连续的 A,同理 4B 表示有 4 个连续的 B,3C 表示有 3 个连续的 C,其它情况以此类推。

但是实际上情况可能会非常复杂,我们可以对单个字符进行编码,也可以对多个字符进行编码。 因此如何提取子序列就是一个问题。这并没有看的那么简单。还是以上面的例子来说,我们有也可以把AAAAABBBBCCC整体看成一个子序列,这样编码的长度就有所编码。究竟使用哪种方法,取决于压缩的时间和压缩的比例等。 更复杂的情况还有很多,这里不做扩展。

对文件进行压缩比较适合的情况是文件内的二进制有大量的连续重复,一个经典的例子就是具有大面积色块的 BMP 图像,BMP 因为没有压缩,所以看到的是什么样子存储的时候二进制就是什么样子

这也是我们图片倾向于纯色的时候,压缩会有很好的效果

思考一个问题, 如果我们在 CDN 上存储两个图片,这两个图片几乎完全一样,我们是否可以进行优化呢?这虽然是 CDN 厂商更应该关心的问题,但是这个问题对我们影响依然很大,值得思考。

总结

游程编码和 Huffman 都是无损压缩算法,即解压缩过程不会损失原数据任何内容。 实际情况,我们先用游程编码一遍,然后再用 Huffman 再次编码一次。几乎所有的无损压缩格式都用到了它们,比如 PNG,GIF,PDF,ZIP 等。

对于有损压缩,通常是去除了人类无法识别的颜色,听力频率范围等。也就是说损失了原来的数据。 但由于人类无法识别这部分信息,因此很多情况下都是值得的。这种删除了人类无法感知内容的编码,我们称之为“感知编码”(也许是一个自创的新名词),比如 JPEG,MP3 等。关于有损压缩不是本文的讨论范围,感兴趣的可以搜素相关资料。

实际上,视频压缩的原理也是类似,只不过视频压缩会用到一些额外的算法,比如“时间冗余”,即仅存储变化的部分,对于不变的部分,存储一次就够了。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

每天一道算法练习题--Day16 && 第一章 --算法专题 --- ----------哈夫曼编码和游程编码 的相关文章

  • C 编程 - 文件 - fwrite

    我有一个关于编程和文件的问题 while current NULL if current gt Id Doctor 0 current current gt next id doc current gt Id Doctor if curre
  • GLKit的GLKMatrix“列专业”如何?

    前提A 当谈论线性存储器中的 列主 矩阵时 列被一个接一个地指定 使得存储器中的前 4 个条目对应于矩阵中的第一列 另一方面 行主 矩阵被理解为依次指定行 以便内存中的前 4 个条目指定矩阵的第一行 A GLKMatrix4看起来像这样 u
  • 按成员序列化

    我已经实现了template
  • 在结构中使用 typedef 枚举并避免类型混合警告

    我正在使用 C99 我的编译器是 IAR Embedded workbench 但我认为这个问题对于其他一些编译器也有效 我有一个 typedef 枚举 其中包含一些项目 并且我向该新类型的结构添加了一个元素 typedef enum fo
  • 使用实体框架模型输入安全密钥

    这是我今天的完美想法 Entity Framework 中的强类型 ID 动机 比较 ModelTypeA ID 和 ModelTypeB ID 总是 至少几乎 错误 为什么编译时不处理它 如果您使用每个请求示例 DbContext 那么很
  • OleDbDataAdapter 未填充所有行

    嘿 我正在使用 DataAdapter 读取 Excel 文件并用该数据填充数据表 这是我的查询和连接字符串 private string Query SELECT FROM Sheet1 private string ConnectStr
  • 如何从 appsettings.json 文件中的对象数组读取值

    我的 appsettings json 文件 StudentBirthdays Anne 01 11 2000 Peter 29 07 2001 Jane 15 10 2001 John Not Mentioned 我有一个单独的配置类 p
  • 关于 C++ 转换:参数 1 从“[some_class]”到“[some_class]&”没有已知的转换

    我正在研究 C 并且遇到了一个错误 我不知道确切的原因 我已经找到了解决方案 但仍然想知道原因 class Base public void something Base b int main Base b b something Base
  • 不同枚举类型的范围和可转换性

    在什么条件下可以从一种枚举类型转换为另一种枚举类型 让我们考虑以下代码 include
  • 堆栈溢出:堆栈空间中重复的临时分配?

    struct MemBlock char mem 1024 MemBlock operator const MemBlock b const return MemBlock global void foo int step 0 if ste
  • C#中如何移动PictureBox?

    我已经使用此代码来移动图片框pictureBox MouseMove event pictureBox Location new System Drawing Point e Location 但是当我尝试执行时 图片框闪烁并且无法识别确切
  • C++ OpenSSL 导出私钥

    到目前为止 我成功地使用了 SSL 但遇到了令人困惑的障碍 我生成了 RSA 密钥对 之前使用 PEM write bio RSAPrivateKey 来导出它们 然而 手册页声称该格式已经过时 实际上它看起来与通常的 PEM 格式不同 相
  • 转发声明和包含

    在使用库时 无论是我自己的还是外部的 都有很多带有前向声明的类 根据情况 相同的类也包含在内 当我使用某个类时 我需要知道该类使用的某些对象是前向声明的还是 include d 原因是我想知道是否应该包含两个标题还是只包含一个标题 现在我知
  • 垃圾收集器是否在单独的进程中运行?

    垃圾收集器是否在单独的进程中启动 例如 如果我们尝试测量某段代码所花费的进程时间 并且在此期间垃圾收集器开始收集 它会在新进程上启动还是在同一进程中启动 它的工作原理如下吗 Code Process 1 gt Garbage Collect
  • 通过指向其基址的指针删除 POD 对象是否安全?

    事实上 我正在考虑那些微不足道的可破坏物体 而不仅仅是POD http en wikipedia org wiki Plain old data structure 我不确定 POD 是否可以有基类 当我读到这个解释时is triviall
  • cmake 将标头包含到每个源文件中

    其实我有一个简单的问题 但找不到答案 也许你可以给我指一个副本 所以 问题是 是否可以告诉 cmake 指示编译器在每个源文件的开头自动包含一些头文件 这样就不需要放置 include foo h 了 谢谢 CMake 没有针对此特定用例的
  • 如何在Xamarin中删除ViewTreeObserver?

    假设我需要获取并设置视图的高度 在 Android 中 众所周知 只有在绘制视图之后才能获取视图高度 如果您使用 Java 有很多答案 最著名的方法之一如下 取自这个答案 https stackoverflow com a 24035591
  • 混合 ExecutionContext.SuppressFlow 和任务时 AsyncLocal.Value 出现意外值

    在应用程序中 由于 AsyncLocal 的错误 意外值 我遇到了奇怪的行为 尽管我抑制了执行上下文的流程 但 AsyncLocal Value 属性有时不会在新生成的任务的执行范围内重置 下面我创建了一个最小的可重现示例来演示该问题 pr
  • IEnumreable 动态和 lambda

    我想在 a 上使用 lambda 表达式IEnumerable
  • 如何将服务器服务连接到 Dynamics Online

    我正在修改内部管理应用程序以连接到我们的在线托管 Dynamics 2016 实例 根据一些在线教程 我一直在使用OrganizationServiceProxy out of Microsoft Xrm Sdk Client来自 SDK

随机推荐

  • KEIL MDK中 warning: #223-D: function "xxx" declared implicitly 解决方法

    今天在EINT的范例里添加了一个函数 即eint c中添加了一个datawrite 的函数 并在主函数main c中调用 编译便警告 warning 223 D function datawrite declared implicitly
  • 详解Shiro认证流程

    详解Shiro认证流程 isAccessAllowed Subject在如何得到 resolveSession doCreateSubject save Subject subject isAuthenticated onAccessDen
  • EditText TextWatch监听简单使用

    TextWatch 接口方法如下 方法执行顺序 beforeTextChanged gt onTextChanged gt afterTextChanged new TextWatcher This method is called to
  • vue 用户列表,请求接口中数据并渲染页面,分页

    参考 vue电商项目实战 哔哩哔哩 bilibili 用户列表 渲染数据 一般数据 1 接口请求数据格式 get方式 传入参数 page rows 2 初始化定义变量 3 联调接口 1 created 2 methods 发送请求 3 接口
  • VulnHub--Me-and-My-Girlfriend-1

    背景 有两个恋人 即Alice和Bob 这对夫妻本来很浪漫 但是自从Alice在一家私人公司 Ceban Corp 工作以来 爱丽丝对鲍勃的态度发生了一些变化是 隐藏 的 而鲍勃 Bob 寻求您的帮助 以获取爱丽丝 Alice 隐藏的内容并
  • MongoDB用户管理授权

    文章目录 1 角色类型 2 注意事项 3 给单个数据库授权 4 给一个用户授权多个数据库 5 其它命令 1 角色类型 数据库用户角色 read readWrite 数据库管理角色 dbAdmin dbOwner userAdmin 集群管理
  • python监控mysql连接数 批量杀进程 解决too many connections问题

    线上django服务偶尔会因为机器访问mysql过多 造成too many connections 问题 导致服务挂掉 之前调大了最大连接数 有点治标不治本 所以今天抽空写个监控mysql连接数的服务 如果连接数超过某个阈值 就杀掉一部分连
  • Linux防火墙未关闭踩的坑—— No route to host

    网络服务很多时候和Linux防火墙都有着很多的关系 经常因为没有关闭Linux防火墙而导致一些奇葩问题的出现 现有两台服务器 S1 和 S2 在 S1 上部署程序 P1 在 S2 上部署 P2 发现 P1 P2 连接报错 日志只有很简单的
  • springcloud 笔记

    提示 本学习笔记是参照尚硅谷视频写的 视频地址 文章目录 第一章 Spring Cloud简介 1 1 什么是SpringCloud 第二章 学习大纲 第三章 SpringCloud和SpringBoot之间的依赖关系如何看 第四章 关于C
  • AI翻译思路引导

    1 基于规则的机器方法 既存储字典和规则沟通 2 基于实例的机器方法 片段化存储的实例 进行组合 数据库一般分词 词汇信息 句法分析 3 基于统计的方法 单词 短语 翻译结果汇总
  • web前端面试总结

    前端面试总结 写React Vue项目时为什么要在列表组件中写Key 其作用是什么 key是给每个vnode的唯一ID 依靠key可以更准确 更快的拿到oldVnode中对应的vnode节点 更准确 因为带key就不是就地复用了 在same
  • QT+机制之信号与槽(自定义带参数的信号)

    关于QT信号与槽的问题其实每个初学QT的人都会遇到 当时我需要做一个带界面的demo 在信号和槽的问题上 我需要的想法是让槽可以有参数的进行操作 但是系统内置的clicked 信号是不含参数的 这对当时根本没接触过QT的我来说就很没头绪 无
  • 90-30-020-源码-任务调度-Kylin任务调度

    1 视界 1 概述 Kylin源码分析系列一 任务调度 注 Kylin源码分析系列基于Kylin的2 6 0版本的源码 其他版本可以类比 Kylin在Web上触发Cube的相关操作后并不是马上执行相关的操作 而是将构建的任务提交到任务调度服
  • 【Java基础知识 1】Java入门级概述,让阿里架构师告诉你为什么要分库分表

    1998年12月8日 第二代Java平台的企业版J2EE发布 1999年4月27日 HotSpot虚拟机发布 2005年6月 在Java One大会上 Sun公司发布了Java SE 6 此时 Java的各种版本已经更名 已取消其中的数字2
  • Dell服务器RAID常用管理命令总结

    介绍 MegaCli是一款管理维护硬件RAID软件 可以通过它来了解当前raid卡的所有信息 包括 raid卡的型号 raid的阵列类型 raid 上各磁盘状态 等等 通常 我们对硬盘当前的状态不太好确定 一般通过机房人员巡检来完成 有没有
  • IP地址的分配

    一 ip地址的作用 用IP地址来标识Internet的主机 IP协议可以根据路由选择协议提供的路由信息对IP数据报进行转发 直至抵达目的主机 IP地址和MAC地址的匹配 数据链路层使用MAC地址来发送数据帧 因此在实际发送IP报文时 还需要
  • centos 安装redis,详细步骤记录下来,直接按步骤即可安装,省大家时间

    一 安装gcc 因为redis是用C语言开发的 安装前要先安装gcc环境 yum install y gcc 二 点击下载redis安装包 三 解压 tar zxvf redis 5 0 3 tar gz cd切换到redis解压目录下 执
  • 智源x清华开源FastMoE,万亿AI模型基石

    北京智源人工智能研究院 以下简称 智源研究院 和清华大学联合发布首个支持PyTorch框架的高性能MoE系统 FastMoE 开源地址 https github com laekov fastmoe FastMoE系统具有易用性强 灵活性好
  • Shell用法

    shell转换大小写用法 把VAR的大写转换成小写 echo VAR tr A Z a z 把VAR的小写转换成大写 echo VAR tr a z A Z shell过滤掉冒号 cat file sed s g sed s g file
  • 每天一道算法练习题--Day16 && 第一章 --算法专题 --- ----------哈夫曼编码和游程编码

    Huffman encode 哈夫曼编码 Huffman 编码的基本思想就是用短的编码表示出现频率高的字符 用长的编码来表示出现频率低的字符 这使得编码之后的字符串的平均长度 长度的期望值降低 从而实现压缩的目的 因此 Huffman 编码