2012-02-25 77 views
0

给出的字节数组:获取指数阵列

{255, 3, 5} 

这相当于:

{11111111, 00000011, 00000101} 

我希望得到以下结果:

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

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

在Java中这样做的最快方式是什么?

更新: 我选择了最快的解决方案,@ aioobe的。这里有一个相当大的数据测试的测试结果:

@ aioobe的方式:

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

@马亭的方式:

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

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

+0

数组可以是任意长度,还是总是3个字节长? – aioobe 2012-02-25 13:27:34

+0

它的长度是任意的。最大索引可以由(numOfBytes * 8) - 1指定。谢谢。 – Motasim 2012-02-25 13:29:19

回答

2

在Java中这样做的最快方法是什么?

据推测由其中lut[yourByte]等于索引用于yourByte的那些阵列类型int[][]的256项查找表。

你那么就做类似

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

然后向后添加偏移量。 – Bill 2012-02-25 13:31:12

+0

感谢@aioobe,不幸的是我不知道如何使用查找表。我会试着看看它们是如何工作的以及如何使用它们并测试代码的速度。再次感谢! – Motasim 2012-02-25 16:05:02

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] 
+0

这真棒@Martijn,你介意给我代码来扭转操作?即从列表中获取原始字节数组?非常感谢你。 – Motasim 2012-02-25 16:02:12

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 

...等等。

我会在今晚做一个测试实施。

+0

感谢@pewpew,问题是我在比特级别上真的很糟糕,而且我很难理解他们的操作。我真的很感激完整的代码片段。谢谢! – Motasim 2012-02-25 16:07:13