逻辑上理解压缩算法

时间:2015-11-26 00:49:16

标签: arrays algorithm io

这个想法在我的脑海中浮现了3年,我在应用它时遇到了问题 我想创建一个压缩算法,将文件大小减半(

e.g。 8 mb至4 mb

并且在编程方面有一些搜索和经验,我理解以下内容 让我们带一个带字母(a,b,c,d)的.txt文件

使用IO.File.ReadAllBytes函数,它给出以下字节数组:(97 | 98 | 99 | 100),根据这个:https://en.wikipedia.org/wiki/ASCII#ASCII_control_code_chart是字母的十进制值。

我想到的是:如何通过将每个2个成员组合成一个成员来将这个4元阵列数学地切割成仅仅2个元素阵列,但是你不能简单地在数学上将两个数字组合起来并简单地逆转他们回来了,因为你有很多可能性,例如 80 | 90:90 + 80 = 170但是没有办法知道170是80 + 90不是100 + 70或110 + 60的结果。
即使你能克服这个问题,你也会受到数组中一个成员的最大字节数(255个字节)的限制。

据我所知,大多数压缩算法使用二进制压缩并且它们都是成功的,但想象一下将文件大小减半,我想听听你的想法。

最诚挚的问候。

1 个答案:

答案 0 :(得分:2)

制作压缩算法不可能使每个文件都变短。证明称为“计数参数”,这很简单:

有长度为L的256 ^ L个可能的文件。

假设有N(L)个可能的文件长度<升。

如果你做数学运算,你会发现256 ^ L = 255 * N(L)+1

因此。你显然无法压缩长度为L的每个文件,因为没有足够的短文件来保存它们。如果你制作的压缩器总是缩短长度为L的文件,那么许多文件必须压缩到相同的较短文件,当然你只能让其中一个文件重新解压缩。

事实上,长度为L的文件的数量是文件较短的文件的255倍,因此您甚至无法压缩长度为L的大多数文件。只有一小部分比例实际上可以缩短

这在comp.compression常见问题中很好地解释(再次): http://www.faqs.org/faqs/compression-faq/part1/section-8.html

编辑:所以也许你现在想知道这些压缩内容是什么......

嗯,绝大多数“长度为L的所有可能文件”都是随机垃圾。无损数据压缩的工作原理是将较短的表示(输出文件)分配给我们实际使用的文件

例如,霍夫曼编码逐字符工作,并使用较少的位来编写最常见的字符。例如,“e”在文本中出现的频率高于“q”,所以它可能只花3位写“e”,而7位写“q”s。几乎不会发生的字节,如字符131,可以用9或10位写入 - 比它们来自的8位字节长。平均而言,你可以用这种方式压缩简单的英文文本。

LZ和类似的压缩器(如PKZIP等)会记住文件中出现的所有字符串,并为已经发生的字符串分配较短的编码,并对尚未看到的字符串进行较长时间的编码。这更好用,因为它考虑了有关每个编码字符的上下文的更多信息。平均而言,写“男孩”比“boe”需要更少的比特,因为“男孩”更频繁地出现,即使“e”比“y”更常见。

由于它只是预测你实际使用的文件的特性,它有点像黑色艺术,不同类型的压缩器在不同类型的数据上工作得更好或更差 - 这就是为什么有这么多不同的算法。