【问题标题】:how to count only 1bits in binary representation of number without loop如何在没有循环的数字的二进制表示中仅计算 1 位
【发布时间】:2019-01-02 10:06:58
【问题描述】:

假设我有两个数字(最小值和最大值)。 `

例如(0 和 9999999999)

最大值可能如此巨大。现在我也有一些其他的号码。它可能介于最小和最大数量之间。 Let's say 15。现在我需要做的是得到15(15,30,45 and so on, until it reaches the maximum number) 的所有倍数。对于每个这些数字,我必须计算它们的二进制表示中有多少个 1 位。 for example, 15 has 4(because it has only 4 1bits).

问题是,我需要一个循环中的循环来获得结果。第一个循环是获取该特定数字的所有倍数(在我们的示例中为 15),然后对于每个倍数,我需要另一个循环来仅计算 1 位。我的解决方案需要很多时间。这是我的做法。

unsigned long long int min = 0;
    unsigned long long int max = 99999999;
    unsigned long long int other_num = 15; 
    unsigned long long int count = 0;

    unsigned long long int other_num_helper = other_num;
    while(true){
        if(other_num_helper > max) break;
        for(int i=0;i<sizeof(int)*4;i++){
            int buff = other_num_helper & 1<<i;
            if(buff != 0) count++; //if bit is not 0 and is anything else, then it's 1bits.
        }

        other_num_helper+=other_num;

    }
    cout<<count<<endl;

【问题讨论】:

  • 如果您正在寻求帮助和改进代码的提示,我建议您访问 (codereview.stackexchange.com)[codereview.stackexchange.com]。否则你能把你的问题说得更清楚吗?
  • cs-fundamentals.com/tech-interview/c/… 寻找分而治之的策略算法。它计算无符号整数的位。对于 unsigned long long,我需要同样的东西。
  • 您可以随时根据您的需要调整给定的解决方案。在这种情况下,您需要更改常量:例如,如果您的 long long 是 64 位,0x55555555 将变为 0x5555555555555555

标签: c++ c algorithm


【解决方案1】:

查看 0 到 2^3 之间数字的位模式

000
001
010
011
100
101
110
111

你看到了什么?

每一位都是4次。

如果进行概括,您会发现 0 和 2^n 之间的数字总共设置了 n*2^(n-1) 位。

我相信您可以将此推理扩展到任意范围。

【讨论】:

  • 但我仍然需要第一个 while 循环,对吗?可以不使用任何循环吗?
  • @ntshetty 是的,例如 n=5 您正在考虑 0 到 32=2^5 之间的数字
【解决方案2】:

这是我对 32 位数字的处理方式。

std::uint16_t bitcount(
    std::uint32_t n
)
{
    register std::uint16_t reg;
    reg = n - ((n >> 1) & 033333333333)
            - ((n >> 2) & 011111111111);
    return ((reg + (reg >> 3)) & 030707070707) % 63;
}

以及来自该计划的支持 cmets:

将 3 位数字视为 4a + 2b + c。如果我们将它右移 1 位,我们有 2a + b。从原始值中减去这个得到 2a + b + c。如果我们将原始的 3 位数字右移两位,我们得到 a,因此再减一次,我们得到 a + b + c,即原始数字的位数。

例程中的第一个赋值语句计算“reg”。八进制表示中的每个数字只是“n”中相应三位位置中 1 的数量。

最后一个 return 语句将这些八进制数字相加以产生最终答案。关键思想是将相邻的八进制数字对相加,然后计算余数模 63。

这是通过将“reg”右移三位来完成的,将其添加到“reg”本身并使用合适的掩码进行与运算。这会产生一个数字,其中六个相邻位的组(从 LSB 开始)包含 n 中这六个位置中 1 的数量。这个数字模 63 得出最终答案。对于 64 位数字,我们必须添加三组八进制数字并使用模数 1023。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-04
    • 1970-01-01
    相关资源
    最近更新 更多