从 1 到 n 的二进制数的计数

Posted

技术标签:

【中文标题】从 1 到 n 的二进制数的计数【英文标题】:Count of binary numbers from 1 to n 【发布时间】:2021-12-14 14:16:48 【问题描述】:

我想找到 1 和 n 之间的数字的数量,这些数字是基数为 2(二进制)的有效数字。

1 ≤ n ≤ 10^9

例如,假设 n 等于 101。

Input: n = 101

在这种情况下,答案是 5

Output: 1, 10, 11, 100, 101 -> 5

另一个例子

Input: n = 13
Output: 1, 10, 11 -> 3

这是我的代码...

#include <iostream>

using namespace std;

int main()

    int n, c = 0;
    cin >> n;
    for (int i = 1; i <= n; ++i)
    
        int temp = i;
        bool flag = true;
        while(temp != 0) 
            int rem = temp % 10;
            if (rem > 1)
            
                flag = false;
                break;
            
            temp /= 10;
        
        if (flag)
        
            c++;
        
    
    cout << c;
    return 0;

但我想要更快的速度。 (只有一个循环或可能没有任何循环)

提前致谢!

【问题讨论】:

惊喜,但二进制的 101 是十进制的 5,这不是巧合。 【参考方案1】:

适合 d 位数字d1 d2 ... dn 的最高二进制数是 b1 b2 ... bn在哪里

bi = 0 if di = 0, and
bi = 1 otherwise.

使用std::to_string 的简单实现:

int max_binary(int input) 
    int res = 0;
    auto x = std::to_string(input);
    for (char di : x) 
        int bi = x == '0' ? 0 : 1;
        res = 2 * res + bi;
    
    return res;

【讨论】:

这个答案几乎是正确的:如果我们看到输入的基数为 10 的数字为 2 或更大,则答案应将 2^length(remaining from to_string(input)) - 1 添加到 res 并返回.试试这个代码,输入 = 20,应该是 3 好吧,你有办法。是什么阻止了你?【参考方案2】:

详情: 在每一步中,如果数字是 1,那么我们将 2 添加到我们拥有的数字的幂。 如果该数字大于 1,则该数字的所有情况都是可能的,我们也可以计算该数字本身并完全改变答案(-1 是因为我们不想计算 0)。

#include <iostream>

using namespace std;

int main()

    long long int n, res = 0, power = 1;
    cin >> n;

    while(n != 0) 
        int rem = n % 10;
        if (rem == 1) 
            res += power;
         else if (rem > 1) 
            res = 2 * power - 1;
        
        n /= 10;
        power *= 2;
    
    cout << res;
    return 0;

【讨论】:

以上是关于从 1 到 n 的二进制数的计数的主要内容,如果未能解决你的问题,请参考以下文章

二进制计数器的模值是啥意思?呀

java二进制,原码反码补码位运算

338. Counting Bits_比特位计数_简单动态规划

二进制小数和IEEE浮点标准

二进制串为1001101生成多项式怎么算

COCI2011:友好数对