移动 Java 位集
我正在使用 java.util.BitSet 来存储密集的位向量。
我想实现一个将位右移 1 的操作,类似于整数上的 >>>
。
是否有库函数可以转换 BitSet?
如果没有,还有比下面更好的方法吗?
public static void logicalRightShift(BitSet bs) {
for (int i = 0; (i = bs.nextSetBit(i)) >= 0;) {
// i is the first bit in a run of set bits.
// Set any bit to the left of the run.
if (i != 0) { bs.set(i - 1); }
// Now i is the index of the bit after the end of the run.
i = bs.nextClearBit(i); // nextClearBit never returns -1.
// Clear the last bit of the run.
bs.clear(i - 1);
// 0000111100000...
// a b
// i starts off the loop at a, and ends the loop at b.
// The mutations change the run to
// 0001111000000...
}
}
I am using a java.util.BitSet
to store a dense vector of bits.
I want to implement an operation that shifts the bits right by 1, analogous to >>>
on ints.
Is there a library function that shifts BitSet
s?
If not, is there a better way than the below?
public static void logicalRightShift(BitSet bs) {
for (int i = 0; (i = bs.nextSetBit(i)) >= 0;) {
// i is the first bit in a run of set bits.
// Set any bit to the left of the run.
if (i != 0) { bs.set(i - 1); }
// Now i is the index of the bit after the end of the run.
i = bs.nextClearBit(i); // nextClearBit never returns -1.
// Clear the last bit of the run.
bs.clear(i - 1);
// 0000111100000...
// a b
// i starts off the loop at a, and ends the loop at b.
// The mutations change the run to
// 0001111000000...
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
为了获得更好的性能,您可以扩展java.util.BitSet实现并避免不必要的数组复制。这是实现(我基本上重用了 Jeff Piersol 实现):
In order to achieve better performance you can extend java.util.BitSet implementation and avoid unnecessary array copying. Here is implementation (I've basically reused Jeff Piersol implementation):
使用 java SE8,可以实现更简洁的方式:
我试图弄清楚如何使用 LongBuffer 来做到这一点,但还没有完全实现它。希望熟悉底层编程的人能够指出解决方案。
提前致谢!!!
With java SE8, it can be achieved more concise way:
I was trying to figure out how to use LongBuffer to do so but not quite got it to work. Hopefully, someone who is familiar with low level programming can point out a solution.
Thanks in advance!!!
这应该可以解决问题:
它会给你一个等于原始位的位集,但没有最低位。
编辑:
要将其概括为 n 位,
That should do the trick:
It will give you a bitset equal to the orginial one, but without the lower-most bit.
EDIT:
To generalize this to
n
bits,另一种可能更有效的替代方案是使用底层的 long[]。
使用bitset.toLongArray()来获取底层数据。相应地移动这些长整型,然后通过 BitSet.valueOf(long[]) 创建一个新的 BitSet 您必须非常小心地移动基础长整型,因为您必须采用低位并将其移入数组中下一个 long 的高位。
这应该允许您使用处理器上本机的位移操作一次移动 64 位,而不是单独迭代每个位。
编辑:基于路易斯·沃瑟曼的评论。这仅在 Java 1.7 API 中可用。我写的时候没意识到这一点。
An alternative which is probably more efficient would be to work with the underlying long[].
Use
bitset.toLongArray()
to get the underlying data. Shift those longs accordingly, then create a new BitSet viaBitSet.valueOf(long[])
You'll have to be very careful shifting the underlying longs, as you will have to take the low order bit and shift it into the high order bit on the next long in the array.This should let you use the bit shift operations native on your processor to move 64 bits at a time, as opposed to iterating through each one separately.
EDIT: Based on Louis Wasserman's comment. This is only available in Java 1.7 API. Didn't realize that when I wrote it.
请找到 BitSet 为“左移”的代码块
Please find this code block where BitSet is "left-shifted"
您可以使用 BigInteger 代替 BitSet。
BigInteger
已经有 ShiftRight 和 ShiftLeft。You can use
BigInteger
instead ofBitSet
.BigInteger
already has ShiftRight and ShiftLeft.这些函数模仿了<<和>>分别是运营商。
These functions mimic the << and >>> operators, respectively.
您可以查看 BitSet
toLongArray
和valueOf(long[])
。基本上获取
long
数组,移位long
并从移位后的数组构造一个新的BitSet
。You can look at the BitSet
toLongArray
and thevalueOf(long[])
.Basically get the
long
array, shift thelong
s and construct a newBitSet
from the shifted array.