【问题标题】:compressing numbers in javascript to binary format将javascript中的数字压缩为二进制格式
【发布时间】:2013-01-13 23:21:11
【问题描述】:

我需要以尽可能少的数据量将以下内容转换为二进制格式(以及后来的恢复)。

my_arr = [
        [128,32 ,22,23],
        [104,53 ,21,25],
        [150,55 ,79,23],
        [104,101,23,8 ],
        [57 ,117,13,21],
        [37 ,135,21,20],
        [81 ,132,23,6 ],
        [81 ,138,7 ,8 ],
        [97 ,138,7 ,8 ]...

数字不超过 399

如果我对每个数字使用 0(连续 8 个 0 = 8)并使用 1 作为分隔符,则第一行如下所示: 010010000000011000100110010011001000 这对于像 99 这样的数字来说真的很长

如果我将每个数字填充为三位数字并将每个数字依次转换为实际二进制,则第一行如下所示: 000100101000000000110010000000100010000000100011 这相当于每个数字 12 个字符。

由于第一个字符永远不会是 4 或以上,我可以通过将 0 视为 00、1 视为 01、2 视为 10 和 3 视为 11 来节省两个数字。因此每个数字 10 个字符 总的来说,这会将大小减少到第一个选项的 90% 左右(平均),但有没有更短的方法?

编辑:是的,作为 1 和 0 的字符串...并且它不需要比原始整数短...只是仅使用 2 个符号的最短可能编写方式

【问题讨论】:

  • 在 JavaScript 中,将整数视为二进制的唯一方法是将其放入 1s 和 0s 的 String 中。字符串的每个字符将占用至少 8 位,这意味着与整数本身所需的内存相比,该字符串是巨大的。
  • 当你说二进制时,你的意思是字面意思,只有数字 0 和 1 作为字符串,还是你的意思是,例如,你可以将 8 个 1 存储为值 0XFF?基本上与@Paul 相同的问题/评论,但措辞不同。

标签: javascript compression


【解决方案1】:

如果这些值均匀分布在 0 到 399 之间,那么一个非常好的编码方式是采用三个值并将它们编码为一个以 400 为基数的三位整数。 IE。 val1 + 400*val2 + 400*400*val3。然后该整数将很好地适合 26 位。四个连续的 26 位值将适合 13 个字节。然后你得到每个值的平均 13/12 字节。

这与您将能够做到的一样好,除非值的分布有偏差,或者如果存在重复或相关性,在这种情况下,您可以进一步压缩它们。

处理细节,可以用编码序列中的字节数来确定值的个数,可能不是3的倍数。如果它不是三的倍数,那么最后会有一个或两个值,每个值都简单地编码为九位。由于从 18 位到 26 位相加需要 8 位,因此计数没有歧义。

【讨论】:

  • 你的意思是18位代表两个值,9位代表1个值,加到最后?我认为你的最后一段可能需要更多的阐述。否则,+1 的答案与我要建议的答案几乎相同。似乎很少有人了解如何将值打包到其他数基中!
【解决方案2】:

一个好的起点是创建由 1 和 0 组成的恒定长度块,这样可以轻松解码字符串。

400 在二进制中是 110010000,这需要 9 个字符来编码每个数字作为其二进制表示,零填充到恒定长度。

编码第一行:

var padTo9 = function( bin ){ 
    while( bin.length<9 ){ bin = "0" + bin; } 
    return bin; 
}
[128,32 ,22,23].map( function(i){ return padTo9( i.toString(2) ) }).join('');

/* result:
"010000000000100000000010110000010111"
*/

解码

"010000000000100000000010110000010111".match(/[0-1]{9}/g).map( function(i){ return parseInt( i, 2 ) });
/* result:
[128, 32, 22, 23]
*/

我认为获得更短字符串的唯一方法是使用可变块长度,这需要添加一些控制符号来告诉解码器以下数字以特定数量的字符编码。但是这些符号必须大于 400 并且仍然有 9 个字符长,所以我认为考虑到数据的随机分布,这无济于事。

【讨论】:

    【解决方案3】:

    最大 399: 2**9是(2**n)>=399的最小实例,每个数可以存储为9位; 将每个转换为二进制,然后连接

    【讨论】:

    • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
    猜你喜欢
    • 1970-01-01
    • 2020-10-17
    • 2016-11-01
    • 1970-01-01
    • 2010-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-12
    相关资源
    最近更新 更多