压缩字符串存储

时间:2010-12-03 09:20:29

标签: c++ algorithm string data-structures compression

假设我有许多包含非平凡长度字符串的对象(约3-4kb)。字符串彼此不同但同时包含许多公共部分/子序列。平均而言,任何单个字符串的80-90%也包含在其他字符串中。是否有一种简单的方法可以自动利用这种巨大的冗余来压缩数据? 理想情况下,解决方案是C ++并且对用户是透明的(即我可以使用它,就好像我访问常规只读const std :: string而是从压缩存储中读取)。

4 个答案:

答案 0 :(得分:3)

在算法上,Lempel–Ziv–Welch可以为所有对象/字符串提供一个字典。

答案 1 :(得分:3)

你可以使用huffman coding实现并不难,还有语言中的zip算法(比如C#和java),你可以使用它们。

另外如果你确定80-90%都重复了,创建一个所有单词的字典,那么对于每个字符串存储字典单词的位置,意味着有一个大的位数组(10000即)并标记相关如果当前字符串中存在bits[i],请将1定位到words[i]。认为每个单词长度是5个字符然后缩写大约需要1/5大小。

答案 2 :(得分:2)

如果字符串的公共部分是常见的,因为它们是由其他字符串组成的,那么您可以通过使用stlport rope类来获得一些牵引力,该类可以像std一样查找全世界:: string,但是在写入时使用带有副本的子串树表示,这使得它们非常节省空间(共享子串共享)并且非常擅长插入和删除(log(n))

何时使用绳索:

  • 您正在制作模板引擎。文档实例是通过替换模板中的不同数据从模板制作的,然后缓存以供将来使用。模板和实例共有的部件只存储一次,并且跨实例共享,插入和删除都很便宜。

何时不使用绳索:

  • 您正在从应用程序的域外部(从磁盘或通过网络)加载许多文档,并在不进行修改的情况下使用它们。如果绳子没有从一根绳子复制到另一根绳子,则绳子不会共用。如果你能负担得起找到共同子串的工作,仍然可以使用绳索来改善你的最终表示。

答案 3 :(得分:1)

就像@Saeed提到的那样,一个简单的霍夫曼编码在这里表现得很好。

字典中没有必要,如果常见词已知apriori(你已经提到它是HTML)。只需使用来自许多HTML文件的统计数据预先计算一个霍夫曼表(请注意,您可以通过单个符号对整个标记进行编码,并且可以根据需要使用多个符号。)