Algorithm 简单来说,压缩通常是如何实现的?

Algorithm 简单来说,压缩通常是如何实现的?,algorithm,compression,Algorithm,Compression,因此,我最近一直在思考如何实现压缩,到目前为止,我假设它可能使用一种“字节签名”键的哈希表,其中包含内存位置值,在扩展相关压缩项时应替换该“字节签名” 这与事实相去甚远吗 压缩通常是如何实现的?不需要一页的答案,简单地说就可以了。查看维基页面 无损压缩算法通常利用统计冗余,以便更简洁无误地表示发送方的数据。无损压缩是可能的,因为大多数真实世界的数据都有统计冗余。例如,在英文文本中,字母“e”比字母“z”更常见,字母“q”后面跟着字母“z”的可能性非常小 另一种压缩,称为有损数据压缩或感知编码,如

因此,我最近一直在思考如何实现压缩,到目前为止,我假设它可能使用一种“字节签名”键的哈希表,其中包含内存位置值,在扩展相关压缩项时应替换该“字节签名”

这与事实相去甚远吗

压缩通常是如何实现的?不需要一页的答案,简单地说就可以了。

查看维基页面


无损压缩算法通常利用统计冗余,以便更简洁无误地表示发送方的数据。无损压缩是可能的,因为大多数真实世界的数据都有统计冗余。例如,在英文文本中,字母“e”比字母“z”更常见,字母“q”后面跟着字母“z”的可能性非常小

另一种压缩,称为有损数据压缩或感知编码,如果某些保真度损失是可接受的,则是可能的。通常,有损数据压缩将以人们如何感知相关数据的研究为指导。例如,人眼对亮度的细微变化比对颜色的变化更敏感。JPEG图像压缩的部分工作原理是“舍入”一些不太重要的信息。有损数据压缩提供了一种在给定压缩量下获得最佳保真度的方法。在某些情况下,需要透明(不可见)压缩;在其他情况下,牺牲保真度以尽可能减少数据量

无损压缩方案是可逆的,因此可以重建原始数据,而有损压缩方案接受一些数据损失,以实现更高的压缩

然而,无损数据压缩算法总是无法压缩某些文件;事实上,任何压缩算法都必然无法压缩任何不包含可识别模式的数据。因此,压缩已经压缩的数据的尝试通常会导致扩展(文本文件通常在压缩后会被压缩得更多,因为符号更少),压缩除了最普通的加密数据之外的所有数据的尝试也会导致扩展

实际上,有损数据压缩也会达到无法再次压缩的程度,尽管极有损算法(例如总是删除文件的最后一个字节)总是会将文件压缩到文件为空的程度

无损压缩与有损压缩的示例如下:

25.888888888
此字符串可以压缩为:

25.[9]8
解释为“二十五点九八”,原始字符串是完全重新创建的,只是以较小的形式编写。在有损系统中,使用

26
相反,原始数据会丢失,这得益于较小的文件大小


压缩算法试图找到重复的子序列,以较短的表示形式替换它们

让我们来看看这个25字节长的字符串
废话废话废话(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位=75位编码单词加上7.8位=56位字典,因此131位(65.5%)

或对于序列:

00 → "lah b"
01 → "B"
10 → "lah!"
11 → not used
0  → "lah b"
10 → "B"
11 → "lah!"
10 0     0     0     0     11
B  lah b lah b lah b lah b lah!
编码字:

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%)

哈夫曼编码法 用于编码频率较高的字符/子字符串,其代码比频率较低的字符/子字符串短:

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 → "!"
或对于序列:

00 → "lah b"
01 → "B"
10 → "lah!"
11 → not used
0  → "lah b"
10 → "B"
11 → "lah!"
10 0     0     0     0     11
B  lah b lah b lah b lah b lah!
现在我们的
废话废话废话可以编码为:

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   !
或对于序列:

00 → "lah b"
01 → "B"
10 → "lah!"
11 → not used
0  → "lah b"
10 → "B"
11 → "lah!"
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%)

实际数字可能不正确。请随意编辑/更正。

无损压缩算法将每个可能的输入转换为不同的输出,以使更常见的输入转换为更短的输出。从数学上讲,不可能对所有可能的输入进行压缩——否则,会有多个输入A和B压缩成相同的形式,所以当你解压缩它时,你会回到A还是回到B?在实践中,大多数有用的信息都有一些冗余,这种冗余符合某些模式;因此,可以有效地压缩数据,因为压缩数据时扩展的情况不会自然出现


例如,JPEG或MP3压缩中使用的有损压缩,其工作原理是通过某种信号近似输入数据,该信号可以用比原始数据更少的位来表示。当你解压它时,你不会得到原始的,但是你通常会得到足够接近的东西。

用非常简单的术语来说,一种常见的压缩形式是压缩。这涉及到用较短的字符串替换较长的重复字符串

例如,如果您有一个如下所示的文件:

"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:00pm”,F=“8:00pm”,G=5:00pm”

然后,相同的内容可以编码为:

A,C,E
B,C,E
A,D,F
A,D,F
A,C,G