找二进制0 和1

找二进制中0和1的个数的问题也是老生常谈考察思维的一道题了。网上关于找二进制中1的个数的已经论述很好,这里也不花太多篇幅讲找到1的个数原理。先直接上代码

    int n=0;
    cin>>n;
    int count=0;

    while(n)
    {
        n=n&(n-1);//消除最右边的1
        count++;
    } 
    cout<<count<<endl;
    return 0;

下面花多一点篇幅来讲讲找到0的个数的方法。
一般来说找到二进制数中0的个数,这个0的个数是相对于从最左边第一个1的位开始往右数起的个数
比如十进制8—->(1000)2 有三个0
那么呢找到0的个数自然只能用右移运算来计算了,但是要注意的是如果输入数是负数的话,最高位作为符号位为置为1(比如-8—–>>>(1000.0000.0000.1000)2),此时右移运算并不会修改符号位,符号位会一直置1,所以不留意的话会出现死循环,这里我们从右边数起的最后一个1的左边的0不是我们要统计的0,所以我们可以先判断这个数是不是负数,最后在正数的基础上来统计,就不会出现死循环了。
下面是代码

    int n=0;
    cin>>n;
    if(n==0) return 1;
    if(n<0) n=-n;
    int count=0;

    while(n)
    {
        if((n&0x01) == 0)
        {
            count++;
        }
        n=n>>1;
    } 
    cout<<count<<endl;
    return 0;

好了,再来贴一段代码。

int n=0;
    cin>>n;//n=1024
    if(n==0) return 1;
    int count=0;

    while(~n)//while(n+1)
    {
        n=n|(n+1);
        count++;
    } 
    cout<<count<<endl;
    return 0;

猜猜count最终的结果是多少?
答案是31。
循环的功能是什么作用呢?结合例子可以猜到,是应该是统计0的个数,不过他是统计一个int类型中全部0的个数,是不是很神奇,原理其实也是位运算,下面我们用一个简单的例子来做解释,假设我们有一个类型只有半个字节的大小即4个位,当全部为置1后退出按程序逻辑就会退出循环。
初始n=8—>(1000)2
第一次运算后
n=(1000)|(1001)
n=1001=9
count=1
~n=0110
n+1=1010
第二次运算后
n=(1001)|(1010)
n=1011=11
count=2
~n=0100
n+1=1100
第三次运算后
n=(1011)|(1100)
n=1111=16
count=3
~n=0,退出循环
n+1=1.0000 //溢出了

可以看出每进行依次运算,都会把最右边的0置为1,知道最后该类型的所有为都为1,此时如果加1的话就会溢出。因此上面的代码可以统计一个输入数的二进制表达中该类型的0的个数。是不是突然觉得位运算很奇妙呢?

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值