我正在制作一款在线游戏,就像许多在线游戏一样,我需要通过互联网传输大量数据,因此我需要能够有效地压缩数据。
例如,我想从我的客户端向服务器发送我的角色坐标。
编辑:是的坏例子,让我改变价值......
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位,则会产生很大的差异。
答案 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 []。