在字节数组中获取1的索引

时间:2012-02-25 13:24:36

标签: java

给定字节数组:

{255, 3, 5}

相当于:

{11111111, 00000011, 00000101}

我想得到以下结果:

{23,22,21,20,19,18,17,16, 9,8, 2,0}

这是输入数组中1的索引数组。

在Java中执行此操作的最快方法是什么?

更新 我选择了最快的解决方案,@ aioobe's。以下是相当大的数据测试的测试结果:

@ aioobe的方式:

35s 289ms
35s 991ms
36s 174ms

@ Martijn的方式:

39s 274ms
39s 879ms
38s 684ms

谢谢大家!感谢您的帮助。

3 个答案:

答案 0 :(得分:2)

  

在Java中执行此操作的最快方法是什么?

大概是int[][]类型的256条目查找表,其中lut[yourByte]等于yourByte中的{1}}索引数组。

然后您只需执行类似

的操作
for (int i = 0; i < bytes.length; i++)
    for (int indexes : lut[bytes[i]])
        appendToResult(indexes + (bytes.length - 1 - i) * 8);

答案 1 :(得分:1)

经过测试的代码(http://ideone.com/7NUjY):

public static List<Integer> getBitsIndices(byte[] input, boolean b)
{
    List<Integer> list = new ArrayList<Integer>();

    for (int i = 0; i < input.length; ++i)
    {
        byte j = input[i];
        for (int k = 7, bit = 1 << 7; k >= 0; --k, bit >>>= 1)
        {
            if ((j & bit) == bit == b)
            {
                list.add((input.length - i) * 8 - (8 - k));
            }
        }
    }

    return list;
}

以这种方式使用:

byte[] input = {(byte) 255, (byte) 3, (byte) 5};
System.out.println(getBitsIndices(input, true));

输出:

[23, 22, 21, 20, 19, 18, 17, 16, 9, 8, 2, 0]

答案 2 :(得分:0)

我会(给定{255,3,5}整数)并且总是最后一位用0x1然后向右移动。 这两种操作都很快并且具有本机CPU支持。

示例:

pos, index = 0; res[];
00000101 AND 0x1 -> TRUE; res[index++] = pos++;
shift right
00000010 AND 0x1 -> FALSE; pos++;
shift right

......等等。

我将在今晚进行测试。