Reputation: 5475
Given the byte array:
{255, 3, 5}
which is equivalent to:
{11111111, 00000011, 00000101}
I'd like to get the following result:
{23,22,21,20,19,18,17,16, 9,8, 2,0}
Which is an array of the indices of 1's in the input array.
What's the fastest way of doing this in Java?
Update: I've chosen the fastest solution, which @aioobe's. Here are the test results of a pretty big data test:
@aioobe's way:
35s 289ms
35s 991ms
36s 174ms
@Martijn's way:
39s 274ms
39s 879ms
38s 684ms
Thanks you all! I appreciate your help.
Upvotes: 0
Views: 410
Reputation: 1628
I would (given {255, 3, 5} in integer) and always the last bit with 0x1 and then shift to the right. Both operations are fast and have native CPU support.
Example:
pos, index = 0; res[];
00000101 AND 0x1 -> TRUE; res[index++] = pos++;
shift right
00000010 AND 0x1 -> FALSE; pos++;
shift right
... and so on.
I will make a test implementation this evening.
Upvotes: 0
Reputation: 68907
Tested code (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;
}
Use it this way:
byte[] input = {(byte) 255, (byte) 3, (byte) 5};
System.out.println(getBitsIndices(input, true));
Output:
[23, 22, 21, 20, 19, 18, 17, 16, 9, 8, 2, 0]
Upvotes: 1
Reputation: 421290
What's the fastest way of doing this in Java?
Presumably by a 256 entry look-up table of the type int[][]
in which lut[yourByte]
equals the array of indexes for the ones in yourByte
.
You then just do something like
for (int i = 0; i < bytes.length; i++)
for (int indexes : lut[bytes[i]])
appendToResult(indexes + (bytes.length - 1 - i) * 8);
Upvotes: 2