如何将许多小整数存储到字节数组中?

时间:2010-10-07 05:19:13

标签: java algorithm compression

我正在制作一款在线游戏,就像许多在线游戏一样,我需要通过互联网传输大量数据,因此我需要能够有效地压缩数据。

例如,我想从我的客户端向服务器发送我的角色坐标。

编辑:是的坏例子,让我改变价值......

X坐标(比如-32到32)。(65个不同的可能值) Y坐标(-32到32)。(65个不同的可能值) Z坐标(-16到16)。(33个不同的可能值)

我知道X在Y之前存储,在发送之前存储在字节数组上的Z之前。

我知道在服务器中X不能低于-31也不高于32,其他值也是如此。

65 * 65 * 33 = 139.425 3个数字= 17位的不同值组合。

7 + 7 + 5 = 19位。

所以如果我要将X存储在前7位中,那么在接下来的7位中存储Y,然后在接下来的5位中存储Z,它将需要19位,我将能够在另一侧读取它们轻松,但由于这3个数字可以采用的所有可能的值组合只需要17位来存储我觉得我在这里失去了空间。 是否有一种使用少于19位压缩这3个数字的好方法?

当然19位和17位都需要3个字节,但如果它是17位和15位,则会产生很大的差异。

5 个答案:

答案 0 :(得分:3)

我相信你所追求的是编码算法,而不是压缩算法。要压缩这些数字,您应该知道有关这些数字的一些额外信息。

对于编码算法:您有65 * 65 * 33 = 139.425个不同的可能值。 Log2(139.425)~17.09因此您需要至少18位来编码任何这些可能的值。 一个简单的编码方案就像你说的那样:

Value = Z*65*65 + Y*65 + X

然后解码它:

X = Value % 65
Y = (Value/65) % 65
Z = (Value/65/65) % 33

现在Value是一个整数。如果要将其存储在字节数组中,可以将该整数拆分为3个字节:

Byte1 = Value & 255;
Byte2 = (Value>>8) & 255;
Byte3 = (Value>>16) & 255;

答案 1 :(得分:2)

许多语言都支持bit-packing,但我没有看到这方面的优势。每个值都小于一个字节,无论它们是否被打包都需要相同的字节数,因此您可以节省打包/解包值所需的少量时间,只需处理它们解压缩。

答案 2 :(得分:1)

可变整数压缩用于Google的协议缓冲区。它被称为varint,非常简单。

http://code.google.com/apis/protocolbuffers/docs/encoding.html#varints

答案 3 :(得分:1)

您可以查看gelasia-compacter

这是一个实用程序,它在字节数组上打包一系列数字,使较小的数字使用较少的空间(并且数字可以长到很长,所以你不必关心特殊的有很大数字的情况),它还有一种方法可以解压缩它们用于字节流(我的意思是,数据可以包含在很多部分)。

使用大量小数字时非常好,并且可以表示非常大的数字,但如果数字太接近预期的int类型的大小,则可能会降低效率。

答案 4 :(得分:0)

我发现这个使用压缩的variant BitSet,你应该看看它。作者声称该算法针对查询速度进行了优化,而不是针对空间,但它总是比Java的BitSet类更节省空间。我认为,如果你通过线路发送大量的coords,你可能会看到改进,而不是将位序列化为BitSet,然后转换为byte []。