如何统计一个数字x中1的个数

如何统计一个数字x中1的个数

提示:异或运算重要知识点系列文章
只要了解异或运算的根本知识点,解决这些问题也就不在话下。

(1)认识异或运算的本质与基本规律,0^x=x,x异或x=0,有交换律,结合律,与顺序无关
(2)数组arr中,有一个数k出现了奇数次,其他数出现偶数次,请找到并打印这个数k
(3)如何把一个数字x最右侧那个1拿出来,变成00…10…的格式


题目

如何统计一个数字x中1的个数


一、审题

示例:x=11
x=1011
其中1的个数为3个


二、解题

暴力解

你可以这么玩,将x转化为字符数组
挨个统计完事
这会o(n)复杂度,还是那句话,N太大,就失效了。
在这里插入图片描述

异或运算最优解

既然又是涉及一个数字的操作,而且又是其中一个位的数,那么考虑一下用位运算,速度就要快很多!
前面我们学过,如何快速获取数字中最右侧那个1
rightOne = x&(x取反+1)
那我这么想:

如果x!=0,循环干:
(1)每次都获取最右侧那个1,让count++计数
(2)然后将x^rightOne,抹掉刚刚那个最右侧的1;(用的就是异或运算的特性)
(3)直到x为0再也没有1了,统计也就结束了

看例子:
x=1011
在这里插入图片描述
每次统计最右侧那个1,然后将其抹掉,这就是异或运算的好处。
获取最右侧那个1是异或公式来的(rightOne = x&(x取反+1))
抹掉它也是异或运算
可见异或运算的妙处!!
因此,快速就将1统计出来了。
手撕代码:

//统计某个二进制数N中的1的个数,这个也是利用上面最右边数字为1的原理
    //先找一个最右边的1出来,然后计数,之后把N中最右边那个1抹除,然后继续统计
    public static void countNof1(){
        int N = 2;
        int count = 0;//计数器
        
        while (N != 0){//在N的1没有被完全抹除之前,继续统计1,并抹除最右边的1
            int rightOne = N & ((~N) + 1);//找当前最右边那个1
            count++;
            N ^= rightOne;//用异或抹掉最右边的1,而不是&,这个不要混淆了
        }
        System.out.println(count);
    }

总结

提示:重要经验:

1)获取最右侧那个1是异或公式来的(rightOne = x&(x取反+1)),抹掉它也是异或运算,可见异或运算的重要性
2)开头的几篇关于异或运算的重要知识点,一定要熟悉掌握。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冰露可乐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值