2

我正在使用非常大的Int列表(可能很大)在 Scala 上工作,我需要压缩它们并将其保存在内存中。

唯一的要求是我可以提取(并解压缩)列表中的第一个数字以使用,而无需触及列表的其余部分。

我有很多好主意,但其中大多数将数字转换为位。例子:

您可以将任意数字x写为元组 |log(x)|,x-|log(x)| 第一个元素,我们将它作为一个字符串 1 和一个 0 在末尾(一元代码)和二进制中的第二个元素。例如:

1 -> 0,1 -> 0 1

...

5 -> 2,1 -> 110 01

...

8 -> 3,0 -> 1110 000

9 -> 3,1 -> 1110 001

...

虽然 Int 占用固定的 32 位内存和长 64 位,但通过这种压缩,x需要2log(x)位进行存储,并且可以无限增长。在大多数情况下,这种压缩确实会减少内存。

您将如何处理此类数据?是否有诸如位数组之类的东西?

在 Scala 中压缩此类数据的任何其他方式?

谢谢

4

1 回答 1

2

根据数据集的稀疏性和范围,您可以将数据保留为增量列表而不是数字。例如,它用于声音压缩,并且可以是有损或无损的,具体取决于您的需要。

例如,如果您有Int数字,但知道它们之间的距离几乎不会超过(有符号)Byte,您可以执行以下字节列表之类的操作:

-1           // Use -1 to imply the next number cannot be computed as a byte delta
0, 0, 4, 0   // 1024 encoded as bytes
1            // 1025 as a delta
-5           // 1020 as a delta
-1           // Next number can't be computed as a byte delta
0, 0, -1, -1 // 65535 encoded as bytes -- -1 doesn't have special meaning here
10           // 65545 as a delta

因此,您不必使用这种特定编码来处理位。但是,实际上,如果没有对特定问题、数据特征等的非常明确的指示,您将不会得到好的答案。

重读您的问题,您似乎没有丢弃将数据转换为位的压缩技术。如果没有,那么我建议 Huffman——如果需要的话可以预测——或者来自 Lempel-Ziv 家族的东西。

而且,不,不幸的是,Scala 没有处理二进制数据的库。虽然 paulp 可能在编译器本身中有类似的东西。

于 2010-06-29T14:34:00.977 回答