游程编码是什么?

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

比如一个字符串:

AAAAABBBBCCC

使用游程编码可以将其描述为:

5A4B3C

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

原字符串需要12个字符才能描述,而使用游程编码压缩之后只需要6个字符就可以表示,还原回去的时候只需要将字符重复n次即可,这是个原理非常简单的算法。

游程编码适用的场景

算法的基本思想是将重复且连续出现的字符进行压缩,使用更简短的方式来描述,这种方式是基于柯氏复杂度的,那么什么是柯氏复杂度呢,比如有这么三个字符串,它们的长度都是100,其中第一个是100个A,第二个是99个A和一个B,第三个是100个完全随机的字符,我们想办法用尽可能短的语言来描述原字符串,描述第一个字符串时可以说“这是100个A”,描述第二个字符串可以说“这是99个A,然后是一个B”,但是描述第三个字符串时应该怎么说呢?比较容易想到的是“这是100个随机字符”,看上去似乎没有问题,但是这里一个比较重要的点是描述信息需要符合这么一个条件,当单独给出对字符串的描述时能够根据描述恢复出原字符串的内容,100个A和先99个A然后是一个B可以,但是100个随机字符太笼统了显然不行,这个描述信息的长度就称之为柯氏复杂度,在这个例子中第一个柯氏复杂度最小,第二第三依次次之。

那么在不同情况下这个编码的效果如何呢,假如采用定长1个字节来描述连续出现次数,并且一个字符占用1个字节,那么描述(连续出现次数,某个字符)需要的空间是2个字节,只要这个连续出现次数大于2就能够节省空间,比如AAA占用3个字节,编码为(3,A)占用两个字节,能够节省一个字节的空间,可以看出连续出现的次数越多压缩效果越好,节省的空间越大,对一个字符编码能够节省的空间等于=连续出现次数-2,于是就很容易推出连续出现次数等于2时占用空间不变,比如AA占用两个字节,编码为(2,A)仍然占用两个字节,白白浪费了对其编码的资源却没有达到节省空间的效果,还有更惨的情况,就是连续出现次数总是为1,这个时候会越压越大,比如A占用一个字节,编码为(1,A)占用两个字节,比原来多了一个字节,这种情况就很悲剧,一个1M的文件可能一下给压缩成了2M(真是效果奇佳啊),这是能够出现的最糟糕的情况,相当于在文件的每一个字节前面都插入了一个多余的字节0X01(这个字节表示连续出现次数为1),这种情况说明不适合使用游程编码,事实上,绝大多数数据的特征都属于第三种情况,不适合使用游程编码。

游程编码的实际例子之文本压缩


在上面的例子中,128个字符的原始数据被压缩成9个字符,大约是原来的7%。

但是上面的不支持数字是个硬伤,为什么不支持数字呢,因为没办法区分一个数字究竟是表示连续出现次数的数字还是重复字符,这个是编码中经常出现的问题,一个很有效的方式是使数据结构化。

啥是结构化呢,看这个“100M22c6t”,表示连续出现次数的数字100占用三个字符,22占用两个字符,6占用1个字符,不是定长的啊,这个时候可以规定我的整个字符串可以从最开始按两个字符进行分组,每一组的第一个字符表示连续出现次数,第二个字符表示连续出现的字符,这样我按照位置区分数据的类型,就能够存储任意字符了。

采用定长表示连续出现次数,但是因为一个字符最大能够表示9,所以同样的数据压缩之后比原来大了一些。

这里表示出现次数为了简单采用的是十进制0-9,也可以将其扩展为十六进制0-F,甚至扩展到无符号0~255,但可能会出现一些不可读字符。

游程编码的实际例子之字节压缩(二进制文件压缩)

前面的例子使用游程编码压缩文本,看起来很好理解,那么游程编码能不能用来压缩二进制文件呢。

二进制文件在内存中的表示是字节,所以需要想办法能够压缩字节,压缩字节和压缩字符其实是一样一样的,还是结构化的存储,每两个字节一组,每组的第一个字节表示连续出现次数,第二个字节表示连续出现的字节。

对文件进行压缩比较适合的情况是文件内的二进制有大量的连续重复,一个经典的例子就是具有大面积色块的BMP图像,BMP因为没有压缩,所以看到的是什么样子存储的时候二进制就是什么样子,来做一个简单的实验,Win+R,输入mspaint打开Windows自带的画图程序,随便涂抹一副具有大面积色块的图片:

保存时选择256色的BMP:

为什么一定要是BMP呢,因为这种算法不压缩,存储二进制的规律与看到的一致,那为什么是256色呢,因为上面写的程序只计算后面一个字节的重复次数,而一个字节能够表示最大256色,如果表示一个像素超过了一个字节,那么上面的代码将很可能越压越大起不到任何作用。

然后对比一下结果:

压缩效果很好。

原来370K的文件压缩后只有7K,是原来的1.9%,相当于98.1%的数据被压掉了,并且是无损压缩。

那么试一下对于颜色比较丰富的256色图图片呢,随便搞一张信息量比较大的贴到画图中然后保存为256色BMP:

效果并不太理想,所以还是具有大面积色块的256色的BMP更合适,当然存储图片时一般也没有使用BMP格式的,太奢侈了,这里只是强行举了一个例子。

另外值得一提的是,因为是边读取边压缩边写入,所以这种也可以读取输入流中的数据写到输出流,不受文件大小的限制可以无限压缩下去。

总之,游程编码适合的场景是数据本身具有大量连续重复出现的内容。

游程编码run length code相关推荐

  1. Run Length Encoding

    游程编码 (Run Length Encoding ) 是一种简单的编码方法,通常用于控制论中对二值图像编码.ACM有一道题目就是关于该编码.见tzu 1149 或poj 1782 .虽然是简单题,我 ...

  2. 游程编码(Run Length Coding)

    游程编码 游程编码 基本介绍 示例1 示例2 游程编码适用的场景 游程编码 游程编码(Run Length Coding,简称RLC)又称游程编码.行程长度编码.变动长度编码 等,是一种统计编码.主要 ...

  3. RLE格式标注文件转为PNG格式(Run Length Encode)

    一.什么是 RLE 格式 在机器视觉领域的深度学习中,每个数据集都有一份标注好的数据用于训练神经网络. 为了节省空间,很多数据集的标注文件使用RLE的格式,比如 kaggle 挑战赛的 Airbus ...

  4. matlab用游程编码压缩图像,基于Matlab的图像压缩编码

    开发与应用 计算机与信息技术 ·23· 基于 Matlab 的图像压缩编码 杨晓 李悦 (贵州大学 计算机与信息学院,贵州 贵阳 550025) 摘 要 本文描述了图像编码压缩方法的主要分类,介绍了每 ...

  5. 第三章 图像编码原理与技术

    3.1.1图像的空间域统计特性 图像的空间域统计特性的概念 图像的相关函数 图像的直方图  1.图像的空间域统计特性 图像的统计特性是指图像信号(亮度.色度)本身,或对它们进行某种方式的处理之后的输出 ...

  6. 图像有损压缩matlab程序,基于Matlab的灰度图像DCT与RLE的混合有损压缩

    人工智能及识别技术本栏目责任编辑:唐一东第5卷第21期(2009年7月)基于Matlab 的灰度图像DCT 与RLE 的混合有损压缩 朱玲芳,刘任任 (湘潭大学信息工程学院,湖南湘潭411105) 摘 ...

  7. DICOM标准及应用——第一讲 DICOM标准概述

    一 什么是DICOM? DICOM是Digital Imaging and COmmunication of Medicine的缩写,是美国放射学会(American College of Radio ...

  8. JPEG编码过程中的霍夫曼编码

    JPEG编码过程中的霍夫曼编码 jpeg文件中的霍夫曼编码分两个部分对DC系数编码和对AC系数的编码. DC系数的编码 编码过程 DC系数的编码由两部分组成, huffman 编码的bitlen + ...

  9. Code First :使用Entity. Framework编程(6) ----转发 收藏

    Chapter6 Controlling Database Location,Creation Process, and Seed Data 第6章 控制数据库位置,创建过程和种子数据 In prev ...

  10. 101 Ruby Code Factoids

    101 Ruby Code Factoids 0) 'methods' method Since almost everything in Ruby is an Object you can type ...

最新文章

  1. mysql中鼠标光标消失了_为什么我这里没有显示鼠标的悬停可改变页面颜色,以为什么我加载了mysql的jar文件还是不能显示报表的内容呢?...
  2. exit(0)什么意思php,php – 文件中的exit(1)导致脚本状态码为0
  3. java代码顺序执行命令_将小程序安装到Java卡的APDU命令的顺序是什么?
  4. python打包软件后报错 :SyntaxError: Non-UTF-8 code starting with ‘\x90‘ in file 的原因及解决方法
  5. 面试题:如何实现丝滑般的数据库扩容
  6. redis和mysql双写一致_缓存与库双写一致,这种“老大难”怎么给它制服?
  7. hisicv200 exfat支持(转)
  8. 如何将知识图谱引入推荐系统?
  9. linux怎么杀掉mpd进程,linux怎么样安装mpd进程管理器
  10. python(12)给文件读写上锁
  11. SQL基本语句1——创建、添加、删除
  12. jwplayer html插件,jwplayer进阶HTML5
  13. 打印表格留标题怎么设置_WPS怎么设置打印表格每页都有标题?
  14. 桩身弹性压缩计算公式_桩身弹性压缩量计算
  15. 【React】9、使用create-react-app(CRA)创建react项目
  16. Namesilo转出域名到US Domain Center美国域名注册商
  17. 基于MATLAB颜色的植物虫害检测识别
  18. 家装企业如何开展网络营销?
  19. 笨方法学Python—ex43:基本的面向对象分析和设计
  20. 施耐德PLC如何实现组态监控和远程维护?

热门文章

  1. WORD2016打印文档时,图片打印不正常的解决方法
  2. 06. Java面向对象——更改器方法和访问器方法
  3. 加载配置文件(xml文件,properties文件)demo
  4. 【小技巧】程序运行结束后弹窗提醒
  5. 求Sn=a+aa+aaa+…+aa…aaa(有n个a)之值,其中a是一个数字,为2。 例如,n=5时=2+22+222+2222+22222,n由键盘输入。...
  6. 布谷鸟过滤器java使用_Redis布隆过滤器与布谷鸟过滤器
  7. 74ls138和与非门设计全减器,用74LS138和门电路设计1位二进制全减器
  8. 最小生成树算法之Prim(普里姆)算法
  9. linux如何配置本地yum,Linux配置本地yum源配置方法
  10. PHP爬虫最全总结2-phpQuery,PHPcrawer,snoopy框架中文介绍