求一个整数中二进制1的个数

题目:求一个整数二进制表示1的个数

第一版:

思路:如果一个整数与1做与运算,结果为1,那么该整数最右边一位是1,否则是0;

int NumberOf1(int n)
{
	int count  = 0;
	while (n)
	{
		if (n&1)//如果一个整数与1做与运算的结果是1,表示该整数最右边是1,否则是0;
		{
			count++;
		}
		n = n>>1;
	}

	return count;
}

缺点:因为代码当中有右移,当是负数的时候,要考虑符号位;如果一个正数,右移之后在最左边补n个0;如果数字原先是负数,则右移之后在最左边补n个1.

最后这个循环会造成死循环。

第二版:

思路:

首先把n与1做与运算,判断n的最低位是不是为1。接着把1左移一位得到2,再和n做与运算,就能判断n的次低位是不是1....这样反复左移,每次能判断

n的其中一位是不是1.

这个解法中循环的次数等于整数二进制的位数,32位的整数需要循环32次。

int NumberOf1Ex(int n)
{
	int count = 0;
	unsigned int key = 1;
	while (key)
	{
		if (n & key)
		{
			count++;
		}
		key = key<<1;

	}
	return count;
}

缺点:

这个解法中循环的次数等于整数二进制的位数,32位的整数需要循环32次。

第三版:

把一个整数减去1,再和原整数做与运算,会把该整数最右边一个1变成0,那么一个整数的二进制表示中有

多少个1,就可以进行多少次这样的操作。

int NumberOf1Ex2(int n)
{
	int count = 0;
	while (n)
	{

		n = n & (n-1);
		++count;
	}

	return count;
}

完整测试代码:

// GetOneNumber.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
using namespace std;

int NumberOf1(int n)
{
	int count  = 0;
	while (n)
	{
		if (n&1)//如果一个整数与1做与运算的结果是1,表示该整数最右边是1,否则是0;
		{
			count++;
		}
		n = n>>1;
	}

	return count;
}

/*
首先把n与1做与运算,判断n的最低位是不是为1。接着把1左移一位得到2,再和n做与运算,就能判断n的次低位是不是1....这样反复左移,每次能判断
n的其中一位是不是1.

这个解法中循环的次数等于整数二进制的位数,32位的整数需要循环32次。
*/
int NumberOf1Ex(int n)
{
	int count = 0;
	unsigned int key = 1;
	while (key)
	{
		if (n & key)
		{
			count++;
		}
		key = key<<1;

	}
	return count;
}

/*
原理:把一个整数减去1,再和原整数做与运算,会把该整数最右边一个1变成0,那么一个整数的二进制表示中有
多少个1,就可以进行多少次这样的操作。

*/

int NumberOf1Ex2(int n)
{
	int count = 0;
	while (n)
	{

		n = n & (n-1);
		++count;
	}

	return count;
}

int _tmain(int argc, _TCHAR* argv[])
{

	cout<<NumberOf1Ex(9)<<endl;
	cout<<NumberOf1Ex2(12)<<endl;
	cout<<NumberOf1Ex(-1)<<endl;

	getchar();

	return 0;
}
时间: 2024-08-28 16:31:38

求一个整数中二进制1的个数的相关文章

spoj 694 求一个字符串中不同子串的个数

SPOJ Problem Set (classical) 694. Distinct Substrings Problem code: DISUBSTR Given a string, we need to find the total number of its distinct substrings. Input T- number of test cases. T<=20; Each test case consists of one string, whose length is <=

高效求一个整数中1的位数

求一个整数中0或1的位数,有很多方法可以使用除法,求余等方法,也可以使用位运算,相比前者效率更高. #include <stdio.h> #include <stdlib.h> //求一个整数 1的位数 int count0(int x) { int num=0; while(x) { num+=x%2; x/=2; } return num; } int count1(int x) { int num=0; while(x) { num+=(x&0x01); x>&

求整型中二进制1的个数

1. 确定二进制1的个数: ->循环死& ->x-1&x ->查表,分写死与动态生成,动态生成方法:BitsSetTable256[i] = (i &1) + BitsSetTable256[i /2]; ->并行位运算: int BitCount4(unsigned int n) {    n = (n &0x55555555) + ((n >>1) &0x55555555) ;    n = (n &0x3333333

求一个数组中最小的K个数

方法1:先对数组进行排序,然后遍历前K个数,此时时间复杂度为O(nlgn); 方法2:维护一个容量为K的最大堆(<算法导论>第6章),然后从第K+1个元素开始遍历,和堆中的最大元素比较,如果大于最大元素则忽略,如果小于最大元素则将次元素送入堆中,并将堆的最大元素删除,调整堆的结构; 方法3:使用复杂度为O(n)的快速选择算法..................... /** * Created by elvalad on 2014/12/8. * 输入N个整数,输出最小的K个 */ impor

求一个二进制数字中为1的个数

function num_length(num){ var str=num.split(“0”).join(""); return str.length; } 这里的输入默认是一个二进制组成的字符串 如果num是一个二进制整型&&前面如果是以0开头 那么num+="";结果会将原来的num以8进制解释,输出是一个以八进制解释的字符串

求出整数中1的个数

输入一个整数,求出它的二进制1的个数.考虑的知识点:负数怎么求,因为计算机中存放都是补码的形式存储一个数.因为正数的源码,反码,补码都是一样,不用考虑.但是负数就要考虑了,比如-0,它的源码应该是10000000 00000000 00000000 000000000 00000000,所以负数要考虑. 下面是代码实现: #ifndef _FINDNUMBEROF1_ #define _FINDNUMBEROF1_ /*================================ Macro

【微软100题】输入一个整数,求该整数的二进制表达中有多少个1

package test; /** 整数的二进制表示中1的个数 题目:输入一个整数,求该整数的二进制表达中有多少个1. 例如输入10,由于其二进制表示为1010,有两个1,因此输出2. 分析: 方法一:把十进制转换成二进制字符数组,遍历该数组,判断1的个数. 方法二:对于一个int n, n&1的结果就是n转化成二进制数后的最后一位的结果.考察了位运算 包括微软在内的很多公司都曾采用过这道题. * @author Zealot * */ public class MS_28 { private

求一个整数的二进制中1的个数

题目:输入一个整数,求该整数的二进制表达中有多少个1.例如输入10,由于其二进制表示为1010,有两个1,因此输出2. 假设该整数为i.首先i和1做与运算,判断i的最低位是不是为1.接着把1左移一位得到2,再和i做与运算,就能判断i的次高位是不是1……这样反复左移,每次都能判断i的其中一位是不是1.基于此,我们得到如下代码 int NumberOf1_Solution(int i) { int count = 0; unsigned int flag = 1; while(flag) { if(

判欧拉回路或求一个图中欧拉图的个数

判欧拉图两个条件首先联通,其次度全部为欧度.那么就很easy了. 题目:hdoj1878 求一个图中欧拉图的个数. 首先通过连通性求出各个子图,然后求子图中奇数度的个数cnt,cnt/2为欧拉图的个数.若子图没有奇数度,则为一个欧拉回路. 题目:hdoj3018Ant Trip 注意这个题目中可能出现孤立点,不算入欧拉图中. AC代码: include include include include include include include include include include