问题引入:
有100万个字符串,他们长度各异,分布在[1,256]这个区间内。请设计一种方法来依次记录这些字符串的长度。
要求:
用尽可能少的空间来存储这些长度。
例子:
例如有下面四个串:
hello (5)
abc (3)
abcd (4)
good morning (12)
可以用2字节来编码他们的长度:5、3编码到第一个字节,4、12编码到第二个字节,最后的二进制表示就是:01010011 10001100。解码的时候,每4位作为一个解码单元即可按顺序解码。
对于上面的例子,你有更好的编码方案吗?
A Step Further:
上面的例子中只有4个字符串,而问题中有100万个字符串,并且注意到其长度分布只在[1,256]之间,我们能不能利用这个特殊的问题结构呢?
首先还是使用最简单的解决方案:每个字符串长度用1字节来编码(2^8 = 256,正好哦)。此时需要的空间为100万字节。
如果这100万个字符串的长度分布具有一定特征呢?比如,1-15字节长的字符串占90%,其余的只占10%,有没有更好的编码方式呢?举个例子,抛砖引玉:
1~15用4bit位来编码,其中1111用来做特征码,表示当前长度不是1-15,需要往后看。16~256用4+8 = 12bit编码,且前4bit恒为1111,后8位填入实际长度。让我们来算一算此时消耗掉的字节数:
0.5Byte * 100w * 90% + 1.5Byte * 100w * 10% = 60w Byte
比直接用1字节编码每个长度节约了40万字节!
上面的例子很极端,实际中可能没有这么好的数据分布。但给我们一个提示:在对数据进行编码前有必要对数据特征进行统计,然后针对统计结果设计合适的编码方案,这样可以节省一定的编码空间。
看到这里,你是不是想到了……
对,Huffman编码!高频率的数据用较少位编码,低频率的数据用较多位编码。但是,为了提高解压速度,特别是在数据频率分布呈现出一定的单调性的时候,我们可以对huffman编码方法进行化简,使得解码时只需要通过判断特征码就可以确定编码方法。具体该怎么做呢?留给天才的你来解决咯~~~
---
note: 长度编码与huffman编码的联系我起初还没想到,是在敲这篇文章的时候边敲边想,突然联系起来的。嗯,一下上升到规范化的理论阶段了^___^