假设你有很多字符串:
{'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
正如您所看到的,gzip
和7z
分别增加了29%-43%和35%-40%。第一个评论是,通过对两种压缩算法进行排序,性能更好,因此假设即尽管压缩率会有所不同,但可以说有好的"好的"订单和"坏"其中:几乎所有压缩算法都比其他排序获得更好的速率。当然有可能是一个"洗牌"数据集的表现会更好,但可能性并不高。我想知道是否存在更高级的方法。毕竟通过排序,字符串可能会以相同的子字符串开头,但另一种排序方式可能会找到共同具有大子字符串的字符串,例如apple
,apples
,dapple
, pineapple
等等。
这个问题很可能 - 就像最有趣的问题一样 - NP-hard,但是我想知道是否存在一些启发式方法可以用来优化字符串压缩,因为字符串的顺序无关紧要。