Python中的运行长度编码(RLE)压缩算法
运行长度编码是一种无损的数据压缩算法。它通过减少重复的、连续的数据来压缩数据,这些数据被称为运行。它是通过存储这些运行的数量,然后再存储数据来实现的。
在这篇文章中,我们将学习更多关于压缩算法的知识,深入了解实现RLE算法并了解其性能。
前提条件
要继续学习本教程,读者应该具备以下条件。
- 对Python有基本了解。
- 熟悉基于笔记本的界面,如Google Colab。也可以使用普通的Python文件。
简介
在了解RLE之前,让我们先看看几个例子。
- 对于文本
AAAAAAAAAAAAAHHHEEM(19个字符),RLE将其编码为13A3H2EM(7个字符)。 - 对于文本
AAAAHHHEEM, HAHA.,它将被编码为4A3H2E1M1,1 1H1A1H1A1.(21个字符)。
从这些例子中,我们看到RLE适合于用少量的运行来压缩大量的数据,例如,图像像素信息。这是因为短的运行可能最终会占用相同的空间,甚至更多,正如我们在第二个例子中看到的那样。
压缩
这是一个使用算法减少文件大小的过程,所产生的文件比原始文件使用更少的存储位。
- 在一个人想向他/她的朋友发送一张图片的情况下,压缩将在源设备上完成,并在目标设备上解压。这使文件能够更快地被发送,并减少了传输数据的开销流量。
- 在WhatsApp等社交媒体应用程序中,我们注意到,收到的图像质量较低,消耗的空间也小得多。对于一些应用程序,我们可以设置要下载的媒体的质量。
- 我们还注意到,在视频流网站上的压缩,在互联网连接不畅时,视频以低质量加载。
压缩算法的类型
压缩算法有两个主要分类类型。
1.无损算法
当信息质量非常重要时,就会使用无损算法。我们试图避免图像质量的损失。
这些过程是可逆的,而且它们的压缩率很低,因为我们不会损失任何信息。
例子包括运行长度编码(RLE)、Huffman编码、算术编码、Shannon-Fanno编码等。
压缩率--我们通过将压缩前的大小和压缩后的大小相除得到这个比率。(
Size before compression/Size after compression)。
2.有损算法
在质量可能受到影响的地方,我们使用有损算法。在这里,我们实现了高的压缩率,因此有更大的尺寸减少。
有损压缩过程是不可逆的,这与无损压缩算法的过程不同。
实施
让我们跳到Python代码中。
创建一个新的笔记本,在第一个单元格中添加以下代码。
def encode_message(message):
encoded_string = ""
i = 0
while (i <= len(message)-1):
count = 1
ch = message[i]
j = i
while (j < len(message)-1):
'''if the character at the current index is the same as the character at the next index. If the characters are the same, the count is incremented to 1'''
if (message[j] == message[j + 1]):
count = count + 1
j = j + 1
else:
break
'''the count and the character is concatenated to the encoded string'''
encoded_string = encoded_string + str(count) + ch
i = j + 1
return encoded_string
上面的代码包含一个函数encode_message() ,参数为message (字符串),要进行编码。
变量,encoded_string ,用于存储编码后的字符串。while 循环以1 (一个索引)的计数初始化,并循环浏览整个信息。最里面的while 循环检查当前索引的字符是否与下一个索引的字符相同。
如果字符相同,计数就会递增到1 。如果不相同,计数和字符就会串联到encoded_string 变量中并返回。
接下来,我们必须写一个函数来解码编码的信息。创建一个新的单元格并粘贴这个代码。
def decode(our_message):
decoded_message = ""
i = 0
j = 0
# splitting the encoded message into respective counts
while (i <= len(our_message) - 1):
run_count = int(our_message[i])
run_word = our_message[i + 1]
# displaying the character multiple times specified by the count
for j in range(run_count):
# concatenated with the decoded message
decoded_message = decoded_message+run_word
j = j + 1
i = i + 2
return decoded_message
函数decode() ,接收包含编码信息的参数our_message 。变量decoded_message 存储解码后的字符串。
while 循环用于将编码后的信息分离成各自的计数run_count ,以及字符run_word ,直到完成。
它包含一个for 循环,用于多次显示由计数指定的字符(run_count)以形成一个字符串。然后,该字符串与decoded_message 变量相连接。这样持续下去,直到解码后的字符串被完整地显示出来。
最后,我们编写显示我们所写内容的方法。再次打开一个新的单元格,添加以下内容。
def display():
# the original string
our_message = "AuuBBBCCCCCCcccccCCCCCCCCCA"
# pass in the original string
encoded_message=encode_message(our_message)
# pass in the decoded string
decoded_message=decode_message(encoded_message)
print("Original string: [" + our_message + "]")
print("Encoded string: [" + encoded_message +"]")
print("Decoded string: [" + decoded_message +"]")
函数,display() ,有要编码和解码的字符串。
然后我们为这个过程调用两个方法。我们将原始字符串传给encode_message() 函数。编码后,它被存储在encoded_message 变量中。
编码后的信息,encoded_message ,被传递给decode_message 函数进行解码。此后,解码后的信息被存储在decoded_message 变量中。
输出将如下图所示。
Original string: [AuuBBBCCCCCCcccccCCCCCCCCCA]
Encoded string: [1A2u3B6C5c9C1A]
Decoded string: [AuuBBBCCCCCCcccccCCCCCCCCCA]
时间复杂度
与其他无损算法相比,该算法的复杂度为O(n) ,如Huffman的复杂度为O(nlogn) ,它的计算成本比RLE高。
结论
最后,我们已经了解了什么是压缩,压缩的类型,运行长度编码算法,以及它在Python中的实现。
编码愉快