2012-02-25 42 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