Java 如何压缩整数序列?

Java 如何压缩整数序列?,java,arrays,multidimensional-array,arraylist,compression,Java,Arrays,Multidimensional Array,Arraylist,Compression,我有一个数组,其中包含-255到+255范围内的数据。阵列可以如下所示: int data[]={234,56,-4,24,56,78,23,89,234,68,-12,-253,45,128}; 在这里,解压时必须保持顺序,例如,在第1项234之后,第56项必须出现 那么,有什么方法可以压缩任何重复模式无法观察到的任意数字序列呢?从-255到255的范围意味着511个值->9位。如果单独使用符号,1位表示符号,1字节表示值 可以将数组写为字节数组,每个字节值都是相关int的绝对值 在一个

我有一个数组,其中包含-255到+255范围内的数据。阵列可以如下所示:

  int data[]={234,56,-4,24,56,78,23,89,234,68,-12,-253,45,128};
在这里,解压时必须保持顺序,例如,在第1项234之后,第56项必须出现


那么,有什么方法可以压缩任何重复模式无法观察到的任意数字序列呢?

从-255到255的范围意味着511个值->9位。如果单独使用符号,1位表示符号,1字节表示值

可以将数组写为字节数组,每个字节值都是相关int的绝对值


在一个单独的区域(一个长的,或者一个字节数组)中,存储符号位。

如果数据中确实没有模式,那么就不可能使用有用的压缩算法。不要费心去尝试

当然,在这种情况下,因为所有的数字都在一个有限的范围n中,那么你的位中有一个模式——即你的高位要么都是0(正),要么都是1(负)

因此,如果您希望合理有效地进行压缩(假设您有足够长的数字数组,这样做是值得的),标准压缩算法(如zip)就可以工作

或者,您可以利用有效使用9位数字的事实。因此,您可以通过将数字排列为9位块的长流,并将其放入字节数组来实现自己的压缩算法。

在您的情况下(当无法观察到重复模式时),可变长度编码可能会对您有所帮助

例如,和总体思路-小的数字只需要编码很少的比特。Exp Golomb编码用于H.264/MPEG-4 AVC视频压缩标准。用它对序列进行编码和解码非常容易,而且实现这种编码也不是很难

编码所有整数的方法是设置一个双射,在编码之前将整数(0,1,-1,2,-2,3,-3,…)映射到(1,2,3,4,5,6,7,…)

例如:

序列(双射后)
[0,2,5,8,5,2]
将被编码为
101100110000110011
-,如您所见-此序列中没有重复模式,但仅用24位编码。

解码过程的简短描述:

  • 从输入流中读取并计算前导零位(直到找到非零位) 位)->零位计数

  • 从输入流读取下一个(零位计数+1)位->二进制

  • 将二进制转换为十进制

  • 返回(十进制-1)

  • 1…->无前导零,零位计数=0->读取下一个1位->[1]…->[1] 是1->1-1=0

    011…->[0]-一个前导零,零位计数=1->读取下2位->[11]…->[11] is 3->3-1=2

    00110…->[00]-两个前导零,零位计数=2->读取下一个3位->[110]…->[110]是6->6-1=5


    等等。

    如果数字基本上是随机且均匀分布的,并且要保持顺序,那么最好是每个符号大约9位。在9位时,单个9位值将不使用,即在2的补码表示中为-256。这很方便,因为您可以使用它作为结束符号来标记列表的结束。然后,您还对列表的长度进行了编码,这无论如何都是需要的。

    这正是zip、gz和其他压缩器所解决的问题。请使用通用压缩算法。除了范围之外,你还有关于数字序列的信息吗?如果它在该范围内基本上是随机的、均匀的分布,并且要保持顺序,那么最好是每个条目大约9位;压缩的唯一方法是删除多余的内容,如果我可以否决我想要的评论。无需挂起:输出消耗的比特数是否比输入少?Yes@NahuelFouilleul压缩仅仅是编码以使用更少的空间;除此之外,这不是在消除冗余吗?他正在消除不需要的每个值的23个额外位,这是什么。但是在这个范围内[0,2,5,8,5,2],所有的数字都小于16。因此每个数字需要4个位。总共需要6*4=24位。那么,压缩在哪里?如果值是均匀分布的,那么可变长度编码将扩展每个值大于9位的数据。只有当较小的值比较大的值更有可能时,可变长度编码才有用。@Debadyuti Maiti我同意Mark Adler的观点。这只是一种压缩序列的方法,其中有很多小值(但也存在大值)。在这种情况下,与使用预定义长度编码相比,它会更好(因为对于大值,您需要扩展代码长度,对于小值,它也适用)。@Debadyuti Maiti另一个例子:使用
    可变长度
    代码
    [0,2,5,8,5,2255,3,4,20]
    ->将编码为
    60位序列。但是,如果您决定对每个值使用固定长度的位字符串->则每个值需要
    8位
    (因为值为255)。而
    [0,2,5,8,5,2255,3,4,20]
    将被编码为
    80位
    序列。只有经常使用较小的值,您才能从中受益。