如果所有整数都具有相同的频率,那么最佳压缩的公平近似值将是ceil(log2(k))
每个整数的位数。您可以在恒定时间内访问这些位数组。
如果k
非常小(如 3),则上述方法可能会浪费大量空间。但是,您可以将固定数量的小整数组合成一个k
基数,这可以更有效地适合固定数量的位(您也可以方便地将结果放入标准大小的字中)。无论如何,您也可以在恒定时间内访问此编码。
如果您的整数没有相同的频率,则最佳压缩可能会从输入的不同部分产生可变的比特率,因此简单的数组访问将不起作用。在这种情况下,良好的随机访问性能需要索引结构:将压缩数据分成大小合适的块,每个块都可以按顺序解压缩,但这一次受块大小的限制。
如果每个数字的频率完全相同,则可以利用这一点节省一些空间——但这可能还不够值得。
n
范围内随机数的熵[0,k)
为n log2(k)
,即log2(k)
每个数字的位数;这是在不利用确切频率的情况下对数字进行编码所需的位数。
每个元素(其中)的f
副本的可区分排列的熵是:k
n=f*k
log2( n!/(f!)^k ) = log2(n!) - k * log2(f!)
应用斯特林近似(仅当n
且f
很大时才适用),产生:
~ n log2(n) - n log2(e) - k ( f log2(f) - f log2(e) )
= n log2(n) - n log2(e) - n log2(f) + n log2(e)
= n ( log2(n) - log2(f) )
= n log2(n/f)
= n log2(k)
这意味着,无论n
大小k
,您都不会通过利用输入的确切频率来获得大量空间。
上述斯特林近似的总误差是O(log2(n) + k log2(f))
,它是O(log2(n)/n + log2(f)/f)
按数字编码的。这确实意味着,如果您k
的数据太大而f
太小(即每个不同的数字只有少量副本),您可以通过巧妙的编码节省一些空间。但是,问题指定k
实际上很小。