如果我有一个长度为500位的Java BitSet,我知道它包含100个整数,每个整数用5位表示,如何提取这些整数的数组?在线使用一些示例,我想出了以下内容:
static int[] bitSet2Ints(BitSet bs, int bitNumber)
{
int[] temp = new int[bs.length() / bitNumber];
for (int i = 0; i < temp.length; i++)
{
for (int j = 0; j < bitNumber; j++)
{
if (bs.get(i * bitNumber + j))
{
temp[i] |= 1 << j;
}
}
}
return temp;
}
我想知道这是否是正确的方法。
谢谢!
编辑:显然,代码不会产生预期的结果。我进行了单元测试,输入和输出完全不同:
这是我的意见:
Binary String: 0 is 00000
Binary String: 1 is 00001
Binary String: 2 is 00010
Binary String: 3 is 00011
Binary String: 4 is 00100
Binary String: 5 is 00101
Binary String: 6 is 00110
Binary String: 7 is 00111
Binary String: 8 is 01000
Binary String: 9 is 01001
Binary String: 10 is 01010
Binary String: 11 is 01011
Binary String: 12 is 01100
Binary String: 13 is 01101
Binary String: 14 is 01110
Binary String: 15 is 01111
Binary String: 16 is 10000
Binary String: 17 is 10001
Binary String: 18 is 10010
Binary String: 19 is 10011
Binary String: 20 is 10100
Binary String: 21 is 10101
Binary String: 22 is 10110
Binary String: 23 is 10111
Binary String: 24 is 11000
Binary String: 25 is 11001
Binary String: 26 is 11010
Binary String: 27 is 11011
Binary String: 28 is 11100
Binary String: 29 is 11101
Binary String: 30 is 11110
Binary String: 31 is 11111
这是我的输出:
NUMBER OF VALUES EXTRACTED: 32
INTEGER CONVERTED: 0
INTEGER CONVERTED: 16
INTEGER CONVERTED: 8
INTEGER CONVERTED: 24
INTEGER CONVERTED: 4
INTEGER CONVERTED: 20
INTEGER CONVERTED: 12
INTEGER CONVERTED: 28
INTEGER CONVERTED: 2
INTEGER CONVERTED: 18
INTEGER CONVERTED: 10
INTEGER CONVERTED: 26
INTEGER CONVERTED: 6
INTEGER CONVERTED: 22
INTEGER CONVERTED: 14
INTEGER CONVERTED: 30
INTEGER CONVERTED: 1
INTEGER CONVERTED: 17
INTEGER CONVERTED: 9
INTEGER CONVERTED: 25
INTEGER CONVERTED: 5
INTEGER CONVERTED: 21
INTEGER CONVERTED: 13
INTEGER CONVERTED: 29
INTEGER CONVERTED: 3
INTEGER CONVERTED: 19
INTEGER CONVERTED: 11
INTEGER CONVERTED: 27
INTEGER CONVERTED: 7
INTEGER CONVERTED: 23
INTEGER CONVERTED: 15
INTEGER CONVERTED: 31
答案 0 :(得分:1)
什么类型的&#34;正确&#34;我们在这说话吗?
您的代码看起来很好,似乎是解决您问题的完美合理方法。如果它取决于我,我会写一些不那么嵌套的东西,以便更容易阅读。也许是这样的:
static byte[] bitSet2Ints(BitSet bs, int bitNumber) {
byte[] temp = new byte[bs.length() / bitNumber];
for (int i = 0; i < temp.length; i++){
temp[i] = bs.get(i * bitNumber, (i + 1) * bitNumber).toByteArray()[0];
}
return temp;
}
*尚未测试此代码
您还可以添加参数检查以避免无效输入:
if (bs == null){
throw new NullPointerException("The bit set cannot be null!");
}
if (bitNumber <1 || bitNumber > 7){
throw new IllegalArgumentException("Illegal bit count");
}
答案 1 :(得分:1)
我想@Malt已经为解决方案提供了最佳的可读性。我希望这是最快的解决方案,因为get(int, int)
创建另一个BitSet
并且检查每个位本身有太多的CPU路径。
我将BitSet
的内部表示复制到新的long
- 数组,然后使用二进制整数算术来获取bitNumber
位的连续部分。
static int[] bitSet2Ints(BitSet bs, int bitNumber) {
if (bitNumber < 1 || bitNumber > Integer.SIZE) {
throw new IllegalArgumentException("bitNumber needs to be between 1 and " + Integer.SIZE);
}
int mask = 0;
for (int i = 0; i < bitNumber; i++) {
mask = mask << 1 | 1;
}
long[] longArray = bs.toLongArray();
int[] result = new int[bs.length() / bitNumber];
for (int i = 0; i < result.length; i++) {
final int globalStartBit = i * bitNumber;
final int localStartBit = globalStartBit % Long.SIZE;
result[i] = (int) (longArray[globalStartBit / Long.SIZE] >>> localStartBit) & mask;
if (Long.SIZE - localStartBit < bitNumber) {
result[i] |= (int) (longArray[globalStartBit / Long.SIZE + 1] << Long.SIZE - localStartBit) & mask;
}
}
return result;
}
当>>>
周围的位周围你可以使用globalStartBit
和<<
周期时,你可以只使用- localStartBit
作为正确的参数。