[英]How to find number of integers in a given range has even set bits
I want to know how many numbers say x, in a given range lets say l and r, l < r, present where number of 1's in binary representation of x is even. 我想知道在给定范围内有多少个数字说x,可以说l和r,l <r,其中x的二进制表示形式中1的个数是偶数。 Is there any efficient way to find that? 有什么有效的方法可以找到吗?
Here's a key fact: 这是一个关键事实:
Suppose we need to count the number of integers in the range [ l , r ) with some property P , and we know how to solve this problem for any range where l is 0. ( "[ l , r )" is a "half-open range": all integers n where l ≤ n < r . 假设我们需要计数的一些属性P的范围[L,R)的整数数量,我们知道如何解决这个问题的任何范围,其中l为0(“[L,R)”是一个“半-open范围“:所有整数n其中L≤ñ<R。 That makes the arithmetic easier.) Then we just need to subtract in order to solve the general problem where l ≠0: COUNT[ l , r ) = COUNT[0, r ) − COUNT[0, l ). 然后,我们只需减去即可解决l ≠0的一般问题:COUNT [ l , r )= COUNT [0, r )-COUNT [0, l )。
The first fact doesn't quite tell us all we need to know, since it only works for even n . 第一个事实并不能完全告诉我们我们需要知道的所有信息,因为它仅适用于n 。 But if n is odd, n-1 is even, and all we need to do is check the parity of n-1 itself, which is the extra number not in the range [0, n -1). 但是,如果n为奇数, n-1为偶数,而我们要做的就是检查n-1本身的奇偶校验,这是不在[0, n -1)范围内的额外数字。
Putting all that together, if we have the range [ l , r ), we compute the count as follows: 将所有内容放在一起,如果我们有范围[ l , r ),我们将按以下方式计算计数:
That last computation requires at most two parity computations, regardless of how large the range is, as well as a couple of divisions and a subtraction. 最后一个计算最多需要两个奇偶校验计算,而不管范围有多大,还要进行两次除法和减法。
If this were a mathematics site, I might feel compelled to prove the assertion in the key fact at the beginning, but since this is CS I will content myself with a proof outline. 如果这是一个数学站点,那么一开始我可能会被迫证明关键事实中的断言,但是由于这是CS,因此我将对证明大纲感到满意。 We first note that if i is even, then PARITY( i ) and PARITY( i +1) are different (since the binary representations only differ in the last bit). 我们首先注意到,如果i为偶数,则PARITY( i )和PARITY( i +1)是不同的(因为二进制表示形式的最后一位不同)。 Conversely, if i is odd, then PARITY( i ) and PARITY( i -1) are different. 相反,如果i为奇数,则PARITY( i )和PARITY( i -1)不同。 Now, take all the integers in [0, n ) and divide them into the set of integers with odd parity and the set with even parity, and consider the homomorphism 现在,取[0, n )中的所有整数并将它们分为具有奇校验的整数集和具有偶校验的整数集,并考虑同构
f ( i )⇒ i +1 if i is even; F(1)⇒ 我 1如果i是偶数;
f ( i )⇒ i −1 if i is odd; F(1)⇒ 我 -1,如果i是奇数;
The image of f over one of the two subsets of [0, n ) is the other subset, since the parity of f ( i ) is different from the parity of i . 在[0, n )的两个子集之一上的f的图像是另一个子集,因为f ( i )的奇偶性不同于i的奇偶性。 So the two subsets are the same size. 因此,两个子集的大小相同。
Assuming that your range falls in positive integer domain, I wrote the following C++ code 假设您的范围属于正整数域,我编写了以下C ++代码
#include <iostream>
#include <cmath>
using namespace std;
int find_even_bits_helper(int upper, int level, bool sign) {
// find even-bit number starting from 0
// level and sign just for printing purpose
for (int i = 0; i <= level; ++i) cout << ' ';
cout << "[0," << upper << "] -> " << '\n';
int answer;
if (upper == -1) {
answer = 0;
}
else if (upper == 0) {
answer = 1;
}
else if ((upper & (upper + 1)) == 0) {
answer = (upper + 1) / 2;
}
else {
int threshold = pow(2, floor(log2(upper)));
int base_part = find_even_bits_helper(threshold - 1, level + 1, sign);
int extra_part = (upper - threshold + 1) \
- find_even_bits_helper(upper - threshold, level + 1, !sign);
// Essentially remove the highest 1 bit, thus all odd-bit becomes even-bit
answer = base_part + extra_part;
}
for (int i = 0; i <= level; ++i) cout << ' ';
if (sign) cout << "+";
else cout << "-";
cout << answer << '\n';
return answer;
}
int find_even_bits(int lower, int upper) {
return find_even_bits_helper(upper, 0, true) \
- find_even_bits_helper(lower - 1, 0, false);
}
int main() {
cout << "Result is: " << find_even_bits(7,34) << '\n';
}
Testing range [7, 34] outputs: 测试范围[7,34]输出:
[0,34] ->
[0,31] ->
+16
[0,2] ->
[0,1] ->
-1
[0,0] ->
+1
-1
+18
[0,6] ->
[0,3] ->
-2
[0,2] ->
[0,1] ->
+1
[0,0] ->
-1
+1
-4
Result is: 14
It shows that [0, 34] has 18 even-bit integers and [0, 6] has 4 even-bit integers. 它显示[0,34]具有18个偶数位整数,[0,6]具有4个偶数位整数。
Therefore, the answer is 18 - 4 = 14
. 因此,答案是18 - 4 = 14
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.