有关如何订购字符串列表以提高压缩性能的建议?

时间:2017-01-19 18:04:20

标签: string sorting compression heuristics

假设你有很多字符串:

{'Ape','Bed','Car','Desk','Edge',...}

并且您必须将该集写入文件。但是字符串出现的顺序是任意的(您只需要存储/检索该集合)。

由于集合可能很大,因此您需要对其进行压缩,例如使用gzip。我对排序集合的方式感兴趣,以便优化压缩率。按字母顺序排序看起来像是一个有价值的候选者,因为它意味着如果gzip压缩"帧",它将看到许多以相同子字符串开头的字符串:在开头它可以进行例如编码AAA更短,最后ZZY可能被编码为短。

我已经通过排序字符串运行了一些测试。例如,测试集strings(92 274个字符串)生成:

-rw-rw-r-- 1 willem willem 296K Jan 19 18:52 strings_norm.gz
-rw-rw-r-- 1 willem willem 419K Jan 19 18:52 strings_shuf.gz

-rw-rw-r-- 1 willem willem 241K Jan 19 19:00 strings_norm.7z
-rw-rw-r-- 1 willem willem 374K Jan 19 19:01 strings_shuf.7z

其中_norm是排序列表,_shuf是其重排列表。这些字符串最初只用utf-8编码,并在字之间添加新行。一个更易于访问的测试集可能是你在大多数Linux发行版上找到的美国词典(可能位于/usr/share/dict/american-english; 99 171个单词):

-rw-rw-r-- 1 willem willem 208K Jan 19 19:40 american_norm.7z
-rw-rw-r-- 1 willem willem 250K Jan 19 19:39 american_norm.gz
-rw-rw-r-- 1 willem willem 352K Jan 19 19:40 american_shuf.7z
-rw-rw-r-- 1 willem willem 439K Jan 19 19:40 american_shuf.gz

这些是通过以下方式生成的:

sort /usr/share/dict/american-english | gzip > american_norm.gz
shuf /usr/share/dict/american-english | gzip > american_shuf.gz
sort /usr/share/dict/american-english | 7z a american_norm.7z -si
shuf /usr/share/dict/american-english | 7z a american_shuf.7z -si

正如您所看到的,gzip7z分别增加了29%-43%和35%-40%。第一个评论是,通过对两种压缩算法进行排序,性能更好,因此假设即尽管压缩率会有所不同,但可以说有好的"好的"订单和"坏"其中:几乎所有压缩算法都比其他排序获得更好的速率。当然有可能是一个"洗牌"数据集的表现会更好,但可能性并不高。我想知道是否存在更高级的方法。毕竟通过排序,字符串可能会以相同的子字符串开头,但另一种排序方式可能会找到共同具有大子字符串的字符串,例如appleapplesdapplepineapple等等。

这个问题很可能 - 就像最有趣的问题一样 - NP-hard,但是我想知道是否存在一些启发式方法可以用来优化字符串压缩,因为字符串的顺序无关紧要。

0 个答案:

没有答案