一个数的二进制表示中1的个数——10

实现一个函数,输入一个整数,输出该数二进制表示中1的个数。例如,将9表示成二进制为1001,有2位是1,因此如果输入数字9,该函数输出2。

如果让我们将一个十进制的数转换成二进制的表示,我们就会不停的模除模除2取它的余数,因此,就可以用这样的方法解决:

#include <iostream>
using namespace std;

size_t count_one_num(int n)
{
    size_t count = 0;

    while(n != 0)
    {   
        if((n % 2) == 1)
            count++;
        n /= 2;
    }   
    return count;
}

int main()
{
    int n = 7;
    size_t ret = count_one_num(n);
    cout<<"one number in "<<n<<" are: "<<ret<<endl;

    return 0;
}

运行程序:

我们知道,任何一个数用机器语言来表示都是0和1的组合,而C/C++中提供了这样的一个运算符,右移操作符“>>”和左移操作符“<<”,它们是将一个数的二进制位进行相应的向左移位和向右移位,而在上面的问题中,可以不断地将整数向右进行移位,这样取到其最低位的数字和1数字进行相与,就能够得知最低位上的数字是1还是0了;

但是提到移位操作符会存在一个问题,当将一个数进行左移时,左边的位会被丢弃,而右边的位会补0;当一个数进行右移操作时,右边的位会被丢弃,那么左边的补位会存在两种情况:一种是逻辑移位,统一都补0;另一种是算数移位,会相应的补符号位;因此,在设计循环判断条件的时候,不能将判断数字是否为0作为循环条件了,而是应当将整数的位数也就是32位作为循环终止的条件,程序如下:

size_t count_one_num(int n)
{
    int i = 32; 
    size_t count = 0;
    while(--i)
    {   
        if((n & 1) == 1)
            ++count;
        n = n>>1;
    }   
    return count;
}

除了上面的方法,其实还有一种利用数字的二进制来解决的办法:可以想到,当一个数不为0的时候,它的二进制表示中至少有一个1,从而计数器就可以加1,然后就需要将二进制中的1一个一个地剔除掉直到数字变为0,那除了移位怎样才能办到呢?可以将数字 =(数字)&(数字-1),因为一个数字减1的时候,它最低位的一个1就会变成0,而最低位的1肯定都是0就会都变成1,也就相当于将数字12的二进制减1就为将1100减1变成了1011值为11,然后将11001011进行相&,那么就会变成1000,也就是成功的将12中的两个1变成了一个1,以此类推就可以统计出二进制中1的个数了,代码实现如下:

size_t count_one_num(int n)
{
    size_t count = 0;
    while(n != 0)
    {   
        ++count;
        n = n & (n-1);
    }   
    return count;
}

这样的代码是不是比前两种更简洁直观呢,只是在理解上要稍微转一下弯。

《完》

时间: 2024-08-29 17:29:00

一个数的二进制表示中1的个数——10的相关文章

位运算--统计一个数的二进制序列中1的个数

给出一个十进制数,求出该数的二进制序列中1的个数.比如 15 的二进制序列是 00000000  00000000  00000000 00001111   1的个数是4. 下边将给出几种不同的解决办法: 方法一: int count_one(int num) { int count = 0; while (num) { if (num % 2 == 1) { count++; } num = num / 2; } return count; } 由于这种方法用到了模除运算,所以这个方法只能处理

输出一个数的二进制序列中1的个数(三种方法)

由于这个数有可能是负数,负数在计算机中以补码的方式存储,要求负数的补码中1的个数依然可以正确输出,方法如下: 1.定义这个数的变量类型为无符号整型(unsigned int) 代码为 include<stdio.h>int count_one_bits(unsigned value){int count=0;while(value){   if(value%2==1)   {count++;   }   value=value/2; }return count;}int main(){unsi

编程之美1——一个数的二进制表示中1的个数

这里要介绍3种解法 第一种:(常规解法) 数在计算机内部都是用二进制表示的,所以可连续用数n除2 代码1: <span style="font-size:14px;">#include <iostream> using namespace std; int main(void) { int n,m; m=0; cin>>n; while(n) { if(n%2) //如果n不能整除2,说明当前n的末尾数为1 m++; n>>=1; //n

【C语言】输入一个整数,输出该数二进制表示中1的个数(三种方法)

输入一个整数,输出该数二进制表示中1的个数.如输入32,输出1. 代码实现: 方法1:与运算 #define _CRT_SECURE_NO_WARNINGS 1 #include<iostream> using namespace std; int FindOneNumber(unsigned int num) {     int numberofOne = 0;     while (num)     {         num = num & (num - 1);         

N!结果二进制表示中1的个数 2.2

个数等于2的因子数+1 ? ? 类似于求一个数二进制表示中1的个数 ? ? 有三种求法,第一种是不断除2,也就是右移,但原问题对负数不能这么做,现在N!结果中不为负数,所以不存在这种问题 ? ? 第二种求法是不断对index乘以2,然后对相应位求与 ? ? 第三种是x&(x-1)不断的判断 ? ? 现提供第四种方法,该方法只适用于阶乘 ? ? ? ?

每天一道算法题:数字二进制形式中1的个数

题目:请实现一个函数,属于一个整数,输出该数二进制表示中1的个数,例如把9表示成二进制是1001,有2位为1.因此如果输入9,该函数输出2. 可能的死循环陷阱 看完题目,相信大家很快就能想到一个解题思路:先判断整数二进制表示中最右边的一位是否为1,接着把输入的整数右移一位,此时原来处于从右边起的第二位被移动至最右边了,再判断是不是1,这样每次移动一位,直到这个整数变成0,即能够得到整数二进制表示形式中1的个数,而现在问题变为如何判断数字的最后一位为1,其实这个也很简单,只需要将数字与1做与运算,

22、输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 思路: n &(n-1)把n的最右边的1去掉,用count++计算1的个数  eg: 101 & 100 = 100   1 class Solution { 2 public: 3 int NumberOf1(int n) { 4 int count = 0; 5             while(n!=0){ 6                 count++; 7                 n = n&

整数的二进制表示中1的个数

给出通常能想到的方式,这两种方式在<C和指针>一书中给出.以下讨论的均为非负整数. /* 该方法每次在循环中判断数的二进制最右一位是否为1(如果该数能不能被2整除). 每次循环后该数右移一位.因此遍历了数的二进制表示的每一位. */ int count_one_bits1(int value) { int count; for (count = 0; value != 0; value >>= 1) if (value % 2 != 0) count++; return count

统计整型数据二进制形式中1的个数

统计整型数据二进制形式中1的个数可以通过如下方式达到: int cnt1bits(int x) { int count = 0; while (x) { ++count; x = x & (x - 1); } return count; }