压缩int []

时间:2014-06-08 16:12:44

标签: java arrays multidimensional-array compression

我想写一个int [] [],由0到x的整数组成(其中x是颜色中的图像数)。目前,我只是写一个列元素,然后是一个分隔符,然后是一个元素,然后重复。然后,当我完成我的专栏后,我会写一个列分隔符并转到下一个。

for (int i = 0; i < imageColors.length; i++) {
    for (int j = 0; j < imageColors[0].length; j++) {
        writer.append(compressedColors[i][j]);
       writer.append("!");
    }
    writer.append("@");
}

我可以逐列编写我的数组并按@分隔,但是有更好的方法可以编写列吗?特别是考虑到很多元素是连续的和相同的,我觉得这可以使用更少的文件空间来完成。只要我能够解码到原始数据,任何事情都会发生。

谢谢!

1 个答案:

答案 0 :(得分:0)

用十六进制编写整数会缩短它们,你只需要记住在阅读它时使用base 16。有时固定长度编码可以通过删除数字分隔符来节省空间,即“!”。这取决于您的号码有多少前导零。此外,如果您的所有数字都适合短或一个字节,那么您可以使用short[][]byte[][]来节省空间。

正如你所说,最重要的可能是游程编码。而不是:

"1234!1234!1234!1234!@"
你有类似的东西:

"r4x1234!@"

同样,您需要重写您的阅读代码以考虑到这一点。 “r”表示这是一个运行长度,而不是一个普通的数字。 “x”将运行长度与要重复的数字分开。

短程可以延长输出;没有压缩方法是完美的。使用"1234!5678!"代替"r1x1234!r1x5678!"

以下是一些运行长度编码的未经测试的代码。我已将其设置为使用十六进制并拒绝短于三的运行。

void writeArray(int[][] imageColors, Writer writer) throws IOException {
    for (int i = 0; i < imageColors.length; i++) {
        writer.append(processRow(imageColors[i]));
        writer.append("@");
    }

}

String processRow(int[] row) {
    int pointer = 0;
    StringBuilder sb = new StringBuilder(DEFAULT_ROW_LENGTH);

    // Set up for first rum.
    int currentValue = row[pointer];
    int repeatCount = 1;
    pointer++;

    while (pointer < row.length) {
        if (row[pointer] == currentValue) {
            // One more value in this run.
            ++repeatCount;
            ++pointer;
        } else {
            // End of run.
            if (repeatCount == 1) {
                sb.append(Integer.toHexString(currentValue));
            } else if (repeatCount == 2) {
                sb.append(Integer.toHexString(currentValue));
                sb.append("!");
                sb.append(Integer.toHexString(currentValue));
            } else {
                // Process long run >= 3.
                sb.append("r"); // "r" for "run".
                sb.append(Integer.toHexString(repeatCount));
                sb.append("x"); // Separate run length from value.
                sb.append(Integer.toHexString(currentValue));
            }
            sb.append("!");

            // Set up for next run.
            currentValue = row[pointer];
            repeatCount = 1;
            pointer++;
        }
    }
    return sb.toString();
}

为了让你高兴,有一段明显的代码遗失了。包括它会使示例变得复杂而不添加任何新内容。我把它作为读者的练习。

相关问题