zoukankan      html  css  js  c++  java
  • 【剑指offer】二进制中1的个数

    题目描写叙述:


           请实现一个函数,输入一个整数,输出该数二进制表示中1的个数。

    比如把9表示成二进制是1001。有2位是1。因此假设输入9,该函数输出2。


    分析描写叙述:

         

           1、对一个整数的二进制形式,要想知道当中1的个数。首先想到的应该就是遍历整个二进制数,用到的方法当然就是移动了(包括左移或右移)。

    比如。用1来跟给定的整数做与运算。

    假设结果为1,则证明整数的二进制形式中。最右边的一位是1。假设结果是0,则证明整数的二进制形式中,最右边的一位是0。

    int NumberOf1(int n)
    {
           int count = 0;
           while(n){
                   if(n & 1)
                             count++;
                   n = n >> 1;
           }
    }


              这样的方法有一个bug,当n是负数时,右移一位的时候。不能简单地把最高位1移到第二位。由于假设移位前是个负数,仍然要保证移位后是个负数,因此移位后的最高位会设为1。假设一直做右移运算,终于整数会变成0xFFFFFFFF而陷入死循环。


             2、针对上面分析的bug,能够不正确n移到,而是对1移动。每次与整数n做完与操作后。就左移一位1……重复左移。每次都能推断整数的某一位是否为1。

    int NumberOf1(int n)
    {
    	int count = 0;
    	unsigned int flag = 1;
    	while(flag){
    		if(n & flag)	
    			count++;
    
    		flag = flag << 1;
    	}
    
    	return count;
    }

             3、另一种更加巧妙的办法:当把一个整数减去1。再和原整数做与运算。会把该整数最右边一个1变成0。那么一个整数的二进制表示中有多少个1,就能够进行多少次这种操作。

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

             技巧:把一个整数减去1之后再和原来的整数做位与运算。得到的结果相当于是把整数的二进制表示中的最右边一个1变成0。

  • 相关阅读:
    移动性能测试 | 持续集成中的 Android 稳定性测试
    iOS 测试 | iOS 自动化性能采集
    Google 测试总监聊如何经营成功的测试职业生涯
    浅谈一下可扩展性网站架构设计
    一条SQL执行慢的原因有哪些
    为什么在做微服务设计的时候需要DDD?
    是时候拥抱.NET CORE了
    MySql多表查询优化
    九种高性能可用高并发的技术架构
    HTTP协议总结
  • 原文地址:https://www.cnblogs.com/liguangsunls/p/6794601.html
Copyright © 2011-2022 走看看