[英]Finding a numbers with the largest/smallest number of bits set
Given a range of integers, how do I find the numbers within the range with the largest and the lowest number of bits set?给定一个整数范围,如何找到设置了最大和最小位数的范围内的数字?
For example, given the range [32, 65]
, 63 has the largest number of bits set (ie six, because the binary representation is 111111
) and 32 and 64 have the lowest (ie one, because the binary representation are 100000
and 1000000
).例如,给定范围
[32, 65]
, 63 设置的位数最多(即 6,因为二进制表示是111111
),而 32 和 64 设置的位数最少(即 1,因为二进制表示是100000
和1000000
)。
Has to work fast for very large numbers/ranges (2^50).对于非常大的数字/范围(2^50),必须快速工作。
Try to find the highest power of 2 that is within the range.尝试找出范围内 2 的最高幂。 This can be done by taking the upper bound and ANDing it with itself minus one in a loop, like:
这可以通过取上限并将其与自身减一在循环中进行 AND 运算来完成,例如:
temp = upper_bound;
while( (temp & (temp-1)) != 0) {
temp = temp & (temp-1);
}
if(temp < lower_bound) {
// No power of 2 found within range
}
If no power of 2 within the range is found by the previous step;如果上一步在范围内没有找到 2 的幂; you would've found a power of 2 that is not in range.
你会发现 2 的幂不在范围内。 Clear the corresponding bit in the upper and lower bounds and recurse;
清除上下界对应位并递归; like:
喜欢:
void find_bits(unsigned int lower_bound, unsigned int upper_bound, unsigned int extra_bits) {
unsigned int temp = upper_bound;
while( (temp & (temp-1)) != 0) {
temp = temp & (temp-1);
}
if(temp < lower_bound) {
find_bits(lower_bound ^ temp, upper_bound ^ temp, extra_bits + 1);
return;
}
If zero is within the range, then the smallest number of set bits is zero (from the number zero).如果零在范围内,则设置位的最小数量为零(从数字零开始)。 Otherwise, the smallest number of set bits is one (from any power of 2 within range, including the highest power of 2 you found).
否则,设置位的最小数量为 1(范围内的任意 2 次幂,包括您找到的最高 2 次幂)。 Don't forget to account for any extra bits that were previously cleared:
不要忘记考虑之前清除的任何额外位:
if(lower_bound == 0) {
least_set_bits = 0 + extra_bits;
} else {
least_set_bits = 1 + extra_bits;
}
If the highest power of 2 within range minus 1 is also within the range, then the largest number of set bits will be however many bits is in highest power of 2 within range minus 1. Otherwise, the upper bound must have been the same as the lower bound and therefore the largest number of set bits is equal to the smallest number of set bits:如果范围负 1 内的 2 的最高幂也在范围内,则设置位的最大数量将是但许多位在范围负 1 内的 2 的最高幂。否则,上限必须与下限,因此最大的设置位数等于最小的设置位数:
if(temp - 1 < lower_bound) {
most_set_bits = least_set_bits;
} else {
temp--;
most_set_bits = 0;
while(temp > 0) {
temp >>= 1;
most_set_bits++;
}
most_set_bits += extra_bits;
}
All of the above combined (and untested and probably buggy; and definitely not able to handle some corner cases - eg if the range is [0, 0]):以上所有组合(并且未经测试并且可能有问题;并且绝对无法处理某些极端情况 - 例如,如果范围是 [0, 0]):
void find_bits(unsigned int lower_bound, unsigned int upper_bound, unsigned int extra_bits) {
unsigned int temp = upper_bound;
unsigned int least_set_bits;
unsigned int most_set_bits;
while( (temp & (temp-1)) != 0) {
temp = temp & (temp-1);
}
if(temp < lower_bound) {
find_bits(lower_bound ^ temp, upper_bound ^ temp, extra_bits + 1);
return;
}
if(lower_bound == 0) {
least_set_bits = 0 + extra_bits;
} else {
least_set_bits = 1 + extra_bits;
}
if(temp - 1 < lower_bound) {
most_set_bits = least_set_bits;
} else {
temp--;
most_set_bits = 0;
while(temp > 0) {
temp >>= 1;
most_set_bits++;
}
most_set_bits += extra_bits;
}
printf("Least set bits is %u, most set bits is %u.\n", least_set_bits, most_set_bits);
}
Given the range [ lower
, upper
] with unsigned
lower
and upper
, let diff = lower ^ upper
be the bits that are different in lower
and upper
.给定范围 [
lower
, upper
] 与unsigned
lower
和upper
,让diff = lower ^ upper
是lower
和upper
不同的位。
If diff
is zero, the lower
and upper
are identical, so the least number of bits and the greatest number of bits set in the range is the number of bits set in lower
.如果
diff
为零,则lower
和upper
相同,因此范围中设置的最少位数和最大位数就是lower
设置的位数。
Otherwise, let n
be the number of the greatest bit set in diff
, starting counting from 0 for the least significant bit.否则,让
n
为diff
设置的最大位的编号,从 0 开始计数最低有效位。 Let mask = (2u << n) - 1
be a mask for the bits up to and including bit n
.让
mask = (2u << n) - 1
是直到并包括位n
的位的掩码。 (Note 2u
is correct.) Partition lower
and upper
into shared high bits and separate low bits: (注
2u
是正确的。)将lower
和upper
划分为共享的高位和单独的低位:
shared = lower & ~mask;
lower &= mask;
upper &= mask;
Count the bits set in shared
.计算
shared
设置的位。 They are necessarily set in any value in the original [ lower
, upper
].它们必须设置为原始 [
lower
, upper
] 中的任何值。 Below, we solve for the new lower
and upper
.下面,我们求解新的
lower
和upper
。 Then the solution for the original values is obtained by adding the number of bits set in shared
.然后通过添加
shared
设置的位数来获得原始值的解决方案。
If lower
is zero, the least number of bits set is zero, since 0 is in [ lower
, upper
], Otherwise, it is one, since 1u << n
is in [ lower
, upper
].如果
lower
为零,则设置的最少位数为零,因为 0 在 [ lower
, upper
] 中,否则为 1,因为1u << n
在 [ lower
, upper
] 中。
If upper
equals mask
, the greatest number of bits set is n+1
, the number of bits set in mask
.如果
upper
等于mask
,则设置的最大位数为n+1
,即mask
设置的位数。 Otherwise, it is n
, since (1u << n) - 1
is in [ lower
, upper
].否则,它是
n
,因为(1u << n) - 1
在 [ lower
, upper
] 中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.