将具有9位数的整数解析为颜色数组

时间:2015-05-26 02:58:41

标签: java

我有一个九位数字的数组,范围为0 - 999,999,999。我希望能够将它们解析为Colors数组。然后我希望能够将颜色数组转换回数字数组。

这是我希望能够做到的:

Color[] colors = encode(intEnter);//intEnter is any integer which is 8 or 9 characters long.
int decode = decode(colors);//returns intEnter

我想做新的Color(999,999,999),但它最多只支持255.

如何创建一个颜色数组来编码比rgb支持的更大的数字,然后将其解码回来?

2 个答案:

答案 0 :(得分:1)

不是将3个字节组合成9位整数,而是使用3个字节创建颜色。但是,您必须先将它们取消签名,以将范围偏移到0255,而不是-128127

考虑您的byte[]大小为100_000个字节:

byte[] bytes = new byte[100_000];

new Random().nextBytes(bytes); //fills array with bytes; simulates bytes from stream

无符号字节值无法容纳byte,因此我们必须使用short[]int[]。要将有符号字节转换为无符号字节,我们对&使用双字255(更常见的是0xff):

int[] unsign(byte[] bytes) {
    int[] unsignedBytes = new int[bytes.length];

    for(int i = 0; i < unsignedBytes.length; i++) {
        unsignedBytes[i] = bytes[i] & 0xff;
    }

    return unsignedBytes;
}

要将这些分组为3,我们需要首先确保我们拥有的字节数可以除以3.例如,如果我们有一个[101, 74, 88, 21]数组,我们可以删除21创建颜色,或添加2 0来创建2种颜色。 第一个选择导致数据丢失,因此我们将使用第二个选项:

int[] sizeArray(int[] unsignedBytes) {
    int length = unsignedBytes.length;
    int bytesPerColor = 3;
    int remainder = length % bytesPerColor;
    int bytesNeeded = bytesPerColor - remainder;

    int numOfBytes = remainder > 0 ? length + bytesNeeded : length;
    int[] sizedArray = new int[numOfBytes];
    System.arrayCopy(unsignedBytes, 0, sizedArray, length);

    return sizedArray;
}

现在进行编码。对于每3个字节,我们生成一个颜色:

Color[] encode(int[] unsignedBytes) {
    Color[] colors = new Color[unsignedBytes.length / 3];

    for(int i = 0, position = 0; i < colors.length; i++) {
        int r = unsignedBytes[position++];
        int g = unsignedBytes[position++];
        int b = unsignedBytes[position++];

        colors[i] = new Color(r, g, b);
    }

    return colors;
}

要解码,只需从每种颜色中获取RGB值:

int[] decode(Color[] colors) {
    int[] unsignedBytes = new int[colors.length * 3];

    int position = 0;
    for(Color color : colors) {
        unsignedBytes[position++] = color.getRed();
        unsignedBytes[position++] = color.getGreen();
        unsignedBytes[position++] = color.getBlue();
    }

    return unsignedBytes;
}

要对字节进行签名,只需将它们转换回字节:

byte[] sign(int[] unsignedBytes) {
    byte[] signedBytes = new byte[unsignedBytes.length];

    for(int i = 0; i < signedBytes.length; i++) {
        signedBytes[i] = (byte) unsignedBytes[i];
    }

    return signedBytes;
}

您可以拥有EncoderDecoder课程,如果需要,可以为您签名并取消签名:

class Encoder {
    public Color[] encode(byte[] signedBytes) {
        return encode(unsign(signedBytes));
    }

    public Color[] encode(int[] unsignedBytes) {
        //...
    }

    private int[] unsign(byte[] signesBytes) {
        //...
    }
}

class Decoder {
    public byte[] decode(Color[] colors) {
        //receive unsigned bytes from colors

        return sign(unsignedBytes);
    }

    private byte[] sign(int[] unsignedBytes) {
        //...
    }
}

通过我的手机写了这个,所以如果有任何问题请告诉我

答案 1 :(得分:0)

我找到了回答我自己问题的方法,但它有点草率。基本上我可以从数字中减去16777215并创建一个颜色,其rgb设置为16777215.它将执行此操作,直到剩下一个数字,它将创建一个剩余数字的颜色。对于数组中的每个数字,它创建一个颜色数组,第一个颜色是数组中有多少颜色组成特定数字的值。

这是我的代码:

1054(?=.*(?:\'\w*\'))|(?<=1054)(?:.*\K(?:\'\w*\'))

编码:

Color[] colors = encode(999999999);
        Color[] colors2 = encode(120658366);
        Color[] colors3 = encode(596820492);
        Color[] colors4 = encode(123098765);
        Color[] colorsFinal = new Color[colors.length + colors2.length + colors3.length + colors4.length];

        int nextIndex=0;
        for(Color c : colors){
            colorsFinal[nextIndex] = c;
            nextIndex++;
        }
        for(Color c : colors2){
            colorsFinal[nextIndex] = c;
            nextIndex++;
        }
        for(Color c : colors3){
            colorsFinal[nextIndex] = c;
            nextIndex++;
        }
        for(Color c : colors4){
            colorsFinal[nextIndex] = c;
            nextIndex++;
        }

        int nextKey = 0;
        for(int i = 0; i < colorsFinal.length; i++){
            if(i == nextKey){
                int count = 1 + (colorsFinal[i].getRGB() + 16777216);
                System.out.println(decode(Arrays.copyOfRange(colorsFinal, i, i + count)));
                nextKey+=count;
                i = nextKey-1;
            }
        }

解码:

public static Color[] encode(int number){
        int count = number / 16777215;
        if(number % 16777215 > 0){
            count++;
        }
        Color[] colors = new Color[count+1];
        for(int i = 0; i < colors.length; i++){
            if(i == 0){
                colors[i] = new Color(count);
            }else{
                if(number > 16777215){
                    number = number - 16777215;
                    colors[i] = new Color(16777215);
                }else{
                    colors[i] = new Color(number);
                }
            }
        }
        return colors;
    }

这是输出:

public static int decode(Color[] colors){
    if(colors.length > 1){
        int total = 0;
        for(int i = 1; i < colors.length; i++){
            total += (colors[i].getRGB() + 16777216);
        }
        return total;
    }else{
        return 0;
    }
}

这可以将9位数字编码为颜色数组,但我相信它可以改进。事实上,这适用于任何积极的整数。