所以我最近一直在考虑如何实现压缩,到目前为止我假设它可能是使用一种具有内存位置值的'字节签名'键的HashTable,其中'字节签名'应该在扩展有问题的压缩物品时更换。
这远非事实吗?
压缩通常如何实施?不需要一个值得回答的页面,只需用简单的术语就可以了。
答案 0 :(得分:63)
压缩算法试图找到重复的子序列,用较短的表示替换它们。
让我们从An Explanation of the Deflate Algorithm获取25字节长的字符串Blah blah blah blah blah!
(200位)。
一种天真的方法是使用相同长度的代码字对每个字符进行编码。我们有7个不同的字符,因此需要长度为ceil(ld(7)) = 3
的代码。我们的代码字可能看起来像这样:
000 → "B"
001 → "l"
010 → "a"
011 → "h"
100 → " "
101 → "b"
110 → "!"
111 → not used
现在我们可以按如下方式对字符串进行编码:
000 001 010 011 100 101 001 010 011 100 101 001 010 011 100 101 001 010 110
B l a h _ b l a h _ b l a h _ b l a !
对于字典,这只需要25·3 bit = 75 bit加上7·8 bit = 56 bit,因此 131位(65.5%)
或者序列:
00 → "lah b"
01 → "B"
10 → "lah!"
11 → not used
编码字:
01 00 00 00 00 10
B lah b lah b lah b lah b lah!
现在我们只需要6·2位= 12位用于编码字,10·8位= 80位加3·8位= 24位用于每个字的长度,因此 116位(58.0%)。
Huffman code用于编码频率较低的字符/子字符串,而不是频繁的代码:
5 × "l", "a", "h"
4 × " ", "b"
1 × "B", "!"
// or for sequences
4 × "lah b"
1 × "B", "lah!"
可能的霍夫曼代码是:
0 → "l"
10 → "a"
110 → "h"
1110 → " "
11110 → "b"
111110 → "B"
111111 → "!"
或者序列:
0 → "lah b"
10 → "B"
11 → "lah!"
现在我们的Blah blah blah blah blah!
可以编码为:
111110 0 10 110 1110 11110 0 10 110 1110 11110 0 10 110 1110 11110 0 10 110 1110 11110 0 10 110 111111
B l a h _ b l a h _ b l a h _ b l a h _ b l a h !
或者序列:
10 0 0 0 0 11
B lah b lah b lah b lah b lah!
现在第一个代码只需要78位或8位而不是25·8 = 200位,就像我们的初始字符串一样。但是我们仍然需要添加存储字符/序列的字典。对于我们的每字符示例,我们需要7个额外字节(7·8位= 56位),并且我们的每序列示例将再次需要7个字节加3个字节用于每个序列的长度(因此为59位)。这将导致:
56 + 78 = 134 bit (67.0%)
59 + 8 = 67 bit (33.5%)
实际数字可能不正确。请随时编辑/更正。
答案 1 :(得分:10)
检查this维基页面...
无损压缩算法通常利用统计冗余,以便更简洁地表示发送方数据而不会出错。无损压缩是可能的,因为大多数真实数据都具有统计冗余。例如,在英文文本中,字母“e”比字母“z”更常见,字母“q”后跟字母“z”的概率非常小。
如果可以接受一些保真度损失,则可以采用另一种称为有损数据压缩或感知编码的压缩。通常,有损数据压缩将通过研究人们如何看待相关数据来指导。例如,人眼对亮度的细微变化比对颜色的变化更敏感。 JPEG图像压缩部分地通过“舍入”一些不太重要的信息来工作。有损数据压缩提供了一种获得给定压缩量的最佳保真度的方法。在某些情况下,需要透明(不明显)的压缩;在其他情况下,牺牲了保真度以尽可能减少数据量。
无损压缩方案是可逆的,因此可以重建原始数据,而有损方案接受一些数据丢失以实现更高的压缩。
但是,无损数据压缩算法总是无法压缩某些文件;实际上,任何压缩算法都必然无法压缩任何不包含可辨别模式的数据。因此,尝试压缩已经压缩的数据通常(文本文件通常可以在压缩后压缩得更多,因为符号更少),导致扩展,尝试压缩除了最简单的加密数据之外的所有数据。
实际上,有损数据压缩也会达到再次压缩不起作用的程度,尽管一个极其有损的算法,例如总是删除文件的最后一个字节,总会压缩文件到达它是空的。
无损与有损压缩的示例如下:
25.888888888
此字符串可以压缩为:
25.[9]8
解释为“二十五点九八”,原始字符串完全重新创建,只是以较小的形式书写。在有损系统中,使用
相反,原始数据会丢失,这样可以减小文件大小。26
答案 2 :(得分:5)
无损压缩算法将每个可能的输入转换为不同的输出,以便更常见的输入转换为更短的输出。 所有可能的输入在数学上是不可能被压缩的 - 否则,你有多个输入A和B压缩到相同的形式,所以当你解压缩它时,你会回到A还是返回到B?实际上,大多数有用的信息都有一些冗余,这种冗余适合某些模式;因此,可以有用地压缩数据,因为压缩它们时扩展的情况不会自然产生。
例如,在JPEG或MP3压缩中使用的有损压缩,通过用一些信号近似输入数据来工作,该信号可以用比原始更少的位表示。当你解压缩它时,你没有得到原始的,但你通常会得到足够接近的东西。
答案 3 :(得分:3)
用非常简单的术语来说,常见的压缩形式是http://en.wikipedia.org/wiki/Dictionary_coder。这涉及用较短的重复字符串替换较长的重复字符串。
例如,如果您有一个如下所示的文件:
"Monday Night","Baseball","7:00pm"
"Tuesday Night","Baseball","7:00pm"
"Monday Night","Softball","8:00pm"
"Monday Night","Softball","8:00pm"
"Monday Night","Baseball","5:00pm"
大约有150个字符,但是如果你在哪里做一个简单的替换如下: A =“星期一之夜”,B =“星期二之夜”,C =“棒球”,D =“垒球”,E =“晚上7:00”,F =“晚上8:00”,G = 5:00pm“
然后相同的内容可以编码为:
A,C,E
B,C,E
A,D,F
A,D,F
A,C,G
使用25个字符!如果我们假设有关文件格式的更多信息,聪明的观察者也可以看到如何轻松地将其进一步减少到15个字符。显然存在替换键的开销,但通常非常大的文件有很多这些替换。这可以是压缩大文件或数据结构的一种非常有效的方法,并且仍然允许它们“在某种程度上”是人类可读的。
答案 4 :(得分:0)
Rosetta Code对霍夫曼编码有一个entry,与我之前的blog entry一样。