《剑指offer》第十五题(二进制中1的个数)

// 面试题:二进制中1的个数
// 题目:请实现一个函数,输入一个整数,输出该数二进制表示中1的个数。例如
// 把9表示成二进制是1001,有2位是1。因此如果输入9,该函数输出2。

#include <iostream>
using namespace std;

//将flag(1)不停左移(右移会出现死循环情况),对每位进行与运算
int NumberOf1_Solution1(int n)
{
    int count = 0;
    unsigned int flag = 1;
    while (flag)//循环次数数据类型的位数
    {
        if (n & flag)//如果该位为1,则表达式成立,count加1
            count++;

        flag = flag << 1;//对flag左移1位
    }

    return count;
}

//更为优秀的算法,循环次数仅为1的个数
//具体思想是,一个整数减去1和这个整数进行与运算,相当于把该整数最右边的1变为0,具体可以手动推导
int NumberOf1_Solution2(int n)
{
    int count = 0;

    while (n)//如果这个整数还不为0
    {
        ++count;
        n = (n - 1) & n;
    }

    return count;
}

// ====================测试代码====================
void Test(int number, unsigned int expected)
{
    int actual = NumberOf1_Solution1(number);
    if (actual == expected)
        cout << "Solution1: Test for " << number << " passed.
";
    else
        cout << "Solution1: Test for " << number << " failed.
";

    actual = NumberOf1_Solution2(number);
    if (actual == expected)
        cout << "Solution2: Test for " << number << " passed.
";
    else
        cout << "Solution2: Test for " << number << " failed.
";

    printf("
");
}

int main(int argc, char* argv[])
{
    // 输入0,期待的输出是0
    Test(0, 0);

    // 输入1,期待的输出是1
    Test(1, 1);

    // 输入10,期待的输出是2
    Test(10, 2);

    // 输入0x7FFFFFFF,期待的输出是31
    Test(0x7FFFFFFF, 31);

    // 输入0xFFFFFFFF(负数),期待的输出是32
    Test(0xFFFFFFFF, 32);

    // 输入0x80000000(负数),期待的输出是1
    Test(0x80000000, 1);

    system("pause");
}

 

原文地址:https://www.cnblogs.com/CJT-blog/p/10478249.html