代码之家  ›  专栏  ›  技术社区  ›  James McMahon

编码0到64之间2个位置的最有效方法?

  •  2
  • James McMahon  · 技术社区  · 15 年前

    我有64位的值,我想通过利用这样一个事实来压缩:中间的某个部分只包含数据,在数据之前和之后都是零。

    假设实际数据是L位长,前面加上N 0,结尾加上M 0,这样N+L+M=64。我不需要发送/存储64位,而是可以发送L位加上我需要的任何内容来编码64位间隔中的数据位置。

    例如,假设我正在存储L、M和数据位,那么我将通过读取L、读取L位数据、读取M并将数据M位向左移动来恢复原来的64位模式。

    我能想到的最小开销是存储L、N和M中任意两个的2乘以6位(每个都可以在0到64之间)。可以减少这个数字吗?

    5 回复  |  直到 15 年前
        1
  •  2
  •   Stephen Denne    15 年前

    l可以是0到64,所以不要发送l,发送n和m,因为它们都可以是0,并且不需要达到64(它们只需要添加到64)。

    L位必须以1开始和结束,因此不需要传输它们。

    为n发送6位
    为m发送最多6位(见下文)
    计算L=64-(N+M)
    如果L=0,则数字为0,不发送任何其他信息
    如果L=1,则数字为1*2^m,不要发送任何其他信息
    如果L=2,则数字为3*2^m,不要发送任何其他信息。
    发送中间的l-2位。

    最大开销=10位。

    m的位数减少是因为
    如果n>32,则您知道m<32,因此只需要5位
    如果n>48,则您知道m<16,因此只需要4位
    如果n>56,那么您知道m<8,因此只需要3位
    如果n>60,那么您知道m<4,因此只需要2位
    如果n=63,那么您就知道m<2,所以只需要1位

        2
  •  4
  •   Michael Borgwardt    15 年前

    你的分析听起来很适合单vlaue。但是,如果您在一起传输大量这样的值,像gzip这样的通用熵编码算法可能会做得更好,因为它可以很好地消除零字符串,并利用数据中的冗余。

        3
  •  3
  •   Stephen C    15 年前

    正如你所说的问题,不,你不能比你提出的解决方案做得更好。

    但是,如果数字中零的分布是倾斜的,那么您可以使用哈夫曼码或类似的技术来表示计数,从而平均获得更好的压缩效果。另一种可能性是,如果零分布从一个64位值强相关到下一个64位值,则使用增量编码。

    在这两种情况下,都需要使用一个可变位数的位来表示零的数目。如果你对歪斜或相关性的假设被证明是错误的,那么你可能会平均使用更多的比特,而不是用简单的方法。

        4
  •  1
  •   Nick Dandoulakis    15 年前

    你的解决方案似乎不错。
    Huffman coding 是压缩值的另一种方法,尤其是在有频率很高的值的情况下。

    实现它并不困难,但是如果没有太多的数据要传输的话,可能会很难。

        5
  •  0
  •   Daniel Brückner    15 年前

    64 可能的起始位置 n 一的序列和序列的长度 l 就不能再这样了 64 - n . 所以有一个

    r = sum(n = 0..63, 64 - n) + 1
    

    序列总数。加上一个表示所有零的序列。做一些数学运算会得到以下结果。

    r = 64 * 64 - (63 * 64) / 2 + 1
      = 2081
    

    表示2081个可能值需要 log2(2081) = 11.023 位。你建议用两个 6 需要的位号 12 因此,总比特数是最佳的(假设所有可能值的分布相等)。