Compressing an int[]



我想写一个由0到x的整数组成的int[][](其中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("@");
}

我可以一列一列地写我的数组,用@分隔,但是有更好的方法我可以写这些列吗?特别是考虑到很多元素是连续的和相同的,我觉得这可以用更少的文件空间来完成。只要我能解码到原始数据,什么都可以。

谢谢!

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

就像你说的,最大的一个可能是运行长度编码。而不是:

"1234!1234!1234!1234!@"

你有这样的东西:

"r4x1234!@"
同样,您需要重写您的读取代码来考虑

。"r"表示这是一个运行长度,而不是一个普通的数字。"x"将运行长度与要重复的数字分开。

较短的运行长度可以延长输出;没有一种压缩方法是完美的。用"1234!5678!"代替"r1x1234!r1x5678!"

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

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();
}

只是为了让您高兴,有一个明显的代码片段丢失了。包含它会使示例变得复杂,而不会添加任何新内容。

相关内容

  • 没有找到相关文章

最新更新