【发布时间】:2018-11-15 18:44:04
【问题描述】:
我正在寻找一种快速迭代掩码中所有可能的位分配的方法。
例子:
掩码 = 0b10011
结果 = {0b00000, 0b00001, 0b00010, 0b00011, 0b10000, 0b10001, 0b10010, 0b10011}
我需要遍历所有这些。
目前我使用与此类似的代码,效果很好:
int count = popCount(mask);
uint64_t number = 0;
for(uint64_t number = 0; number < (1 << count); ++number)
{
uint64_t result = shiftBits(mask, number, count);
//work with result
//only some light operations
}
// shiftBits(0b10011, 0b101, 3) == 0b10001
// shiftBits(0b10011, 0b111, 3) == 0b10011
// shiftBits(0b10011, 0b000, 3) == 0b00000
uint64_t shiftBits(uint64_t mask, uint64_t number, int count) {
uint64_t result = 0;
for(int i = 0; i < count; ++i)
{
uint64_t least = (mask & ~(mask - 1)); // get uint64_t with only least significant 1 set
uint64_t bitSet = number & uint64_t(1); // check if last bit in number is set
result |= least * bitSet; // if last bit is set, then set corresponding position in result
mask &= mask - 1; // clear lsb set in mask
number = number >> 1; // make 2nd lsb the next one to check
}
return result;
}
shiftBits 示例:
mask = 0b10011001
number = 0b1 01 0 = 0b1010
result = 0b10001000
但我想知道是否有人知道在 shiftBits 中执行操作的更快方法,或者是否有更快的方法来创建此分配。 也许是一些位魔术或没有“写后读”和“读后写”冲突的方式?
【问题讨论】:
-
我无法理解
shiftBits应该做什么?从给定的示例看起来,结果包含0和所有非零数字,其&的掩码不等于零。count代表什么? -
它将最低有效位从数字移动到掩码中最低有效 1 的位置。掩码中为 0 的位置在结果中保持为 0。
-
我认为你不能比
O(k 2^k)更快,其中 k 是找到结果集的设置位数。 -
是否允许使用
pdep内在函数?仅适用于现代 x86,在 Ryzen 上运行缓慢
标签: c++ bit-manipulation