键指offer——面试题15:二进制中1的个数(p99-103)

题目描述

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

例:9的二进制表示为1001,有2位是1。

经典解法(超时)

分析:
让一个flag = 1,然后与n相与,相与结果为1的话就证明最后一个位置为1;
然后让flag不断左移,与n相与,最终用count变量统计到原数n中1的个数。

经典解法代码:

//求二进制中1的个数
#include
using namespace std;

int main()
{
     
	//经典解法
	int n = 10;
	int flag = 1;
	int count = 0;
	while(flag)//32位的int整数需要循环32次
	{
     
		if(n&flag)//判断该位置是不是1,这个flag在不断移动
		{
     
			count++;
		}
		flag = flag<<1;
	}
	cout<<count<<endl;

	return 0;
}

升级解法(AC)

分析:
其实就是n = n&(n-1);,每操作一次,n中的1就少一个,直到n变成0了结束统计循环。
总结1:将一个整数减去1,都是把最右边的1变成了0。如果右边还有0,则所有的0都变成1,而他的左边所有位都保留。
总结2:把一个整数减去1,再和原整数做与运算,会把该整数最右边的1变成0【举一反三其他应用】。 要统计一个整数的二进制中有多少个位是1,就看可以进行多少次这样的操作。

代码:

//升级解法
	int n =10;
	int count = 0;
	while(n)
	{
     
		count++;
		n = n&(n-1);
	}
	cout<<count<<endl;
	return 0;

拓展

  1. 用一条语句判断一个整数是不是2的整数次方。
    分析:
    一个整数如果是2的整数次方,那么它的二进制表示中有且只有一位是1,而其他未位就都是0.

代码:

if((n&(n-1)) == 0)
	return 1;
  1. 输入两个整数m和n,计算m和n的二进制位数不同的个数。
    分析:
    先让m和n异或,这样得到的m和n的位不同的位置就是1,相同就为0,然后就是用以上的统计方法进行统计1的个数就行。

代码:

x = m^n;
while(x)
{
     
	count++:
	x = x&(x-1);	
}

  1. 左移和右移
    左移:右边补0
    右移:左边补0.无符号补n个0,有符号补n个1。

你可能感兴趣的:(剑指offer,算法,python,算法,数据结构,leetcode)