我正在寻找一种压缩小型文本字符串的算法:50-1000字节(即URL)。哪种算法最适合这种情况?
我正在寻找一种压缩小型文本字符串的算法:50-1000字节(即URL)。哪种算法最适合这种情况?
请看Smaz:
Smaz是一个简单的压缩库,适用于压缩非常短的字符串。
string:orig_size:compr_size:space_savings
):This is the very end of it. : 27:13:52%
, Lorem ipsum dolor sit amet:26:19:27%
, Llanfairpwllgwyngyll:20:17:15%
, aaaaaaaaaaaaa:13:13:0%
, 2BTWm6WcK9AqTU:14:20:-43%
, XXX:3:5:-67%
。 - mykhalHuffman有静态成本——Huffman表,所以我不认为它是一个好选择。
虽然有一些自适应版本可以避免这种成本,但可能会降低压缩率。实际上,你应该问的问题是“用哪个算法来压缩具有这些特点的文本字符串”。例如,如果预计有很长的重复,简单的游程编码就足够了。如果你能保证只有英语单词、空格、标点符号和偶尔的数字出现,那么带有预定义的Huffman表的Huffman可能会产生良好的结果。
总的来说,Lempel-Ziv家族的算法具有非常好的压缩和性能,而且有很多库可供使用。我会选择它们。
根据被压缩的内容是URLs这一信息,那么在压缩之前,我建议您对它们进行编码。URL遵循明确定义的模式,其中某些部分是高度可预测的。利用这种知识,您可以将URL编码成更小的形式,并且汉弗曼编码背后的思想可以帮助您实现这一点。
例如,将URL翻译成位流,可以用1来替换"http",用0位和实际协议(或使用表来获取其他常见协议,比如https、ftp、file)后面的位数来表示其他任何内容。 "://"可以完全省略,只要你能标记协议的结束。等等。去阅读一下URL格式,并思考一下它们如何被编码成更小的形式。
我手头没有代码,但我一直喜欢建立一个大小为256 * 256个字符的二维查找表的方法(RFC 1978, PPP Predictor Compression Protocol)。要压缩字符串,您循环遍历每个字符并使用查找表获取当前和上一个字符作为索引的“预测”的下一个字符。如果匹配成功,则写入单个1位,否则写入0位、字符并更新查找表。该方法基本上维护了数据流中最可能出现的下一个字符的动态(且粗略的)查找表。
您可以从零开始建立查找表,但是如果对于每个字符对,例如英语,将其初始化为最可能的字符,它在非常短的字符串上运行最佳。只要初始查找表在压缩和解压缩时相同,您就不需要将其发射到压缩的数据中。
这种算法不能提供出色的压缩比率,但它非常节省内存和CPU资源,并且也可以处理连续的数据流——解压缩器在解压缩时维护它自己的查找表,因此查找表会调整到正在压缩的数据类型。
任何支持预设词典的算法/库,例如zlib。
这样,您可以使用与输入中可能出现的相同类型的文本来初始化压缩器。如果文件在某种方式上相似(例如所有URL、所有C程序、所有StackOverflow帖子、所有ASCII艺术图),则某些子字符串将出现在大多数或所有输入文件中。
每个压缩算法都会节省空间,如果同一子字符串在一个输入文件中被重复多次出现(例如英文文本中的“the”或C代码中的“int”)。
但是,在URL的情况下,某些字符串(例如“http://www。”、“.com”、“.html”、“.aspx”)通常每个输入文件只会出现一次。因此,您需要以某种方式在文件之间共享它们,而不是在每个文件中有一个压缩后的实例。将它们放在预设词典中即可实现此目的。
霍夫曼编码通常对此工作效果良好。
Name | Text | Binaries | Raw images
-----------+--------------+---------------+-------------
7-zip | 19% in 18.8s | 27% in 59.6s | 50% in 36.4s
bzip2 | 20% in 4.7s | 37% in 32.8s | 51% in 20.0s
rar (2.01) | 23% in 30.0s | 36% in 275.4s | 58% in 52.7s
advzip | 24% in 21.1s | 37% in 70.6s | 57& in 41.6s
gzip | 25% in 4.2s | 39% in 23.1s | 60% in 5.4s
zip | 25% in 4.3s | 39% in 23.3s | 60% in 5.7s