[蓝蓝计算机考研算法]-day22计算二进制数中1的个数

257 阅读1分钟

题目描述

输入一个整数n,输出该数32位二进制表示中1的个数。其中负数用补码表示。 数据范围:-2^31 <= n <= 2^31-1,即范围为:-2147483648<= n <= 2147483647 。

示例

输入:10
输出:2
说明:十进制中10的32位二进制表示为0000 0000 0000 0000 0000 0000 0000 1010,其中有两个1。

输入:-1
输出:32
说明:负数使用补码表示,-1的32位二进制表示为1111 1111 1111 1111 1111 1111 1111 1111,其中32个1。

思路

  1. 首先要明白,十进制转二进制核心:取模2、取余2、取模2、取余2...余数即为二进制数,且是倒着输出的,比如余数得到的为1101,但其二进制数表示应反过来,为1011。

  2. 若n>0,余数就是1,0的组合,将余数1存进数组中,最后输出数组个数即可。

  3. 若n<0,求的是补码,要负数的补码怎么转换:先讲负数变为正数,然后写出正数的二进制表示,从右向左开始,遇到的第一个1,接下来的数就全部都要变成1,这就是负数的补码。

  4. n<0,求其二进制1的个数的思路为:先将负数转为正数,然后将转化的二进制数全部存进数组中,判断何时从1开始,然后用总位数32减去第一个1的下标,即可得到全部1的个数。

具体实现

#include<bits/stdc++.h>
using namespace std;
int main(){
	int n,a[100],i=0,x;
	cin>>n;
	if(n>0){
		while(n>0){
			x=n%2; 
			if(x==1) a[i++]==x; //将1存放进数组中 
			n/=2;
		}
		cout<<i; //输出数组的总个数 
		
	}else{
		int k = abs(n); //取绝对值,将n变为正数 
		while(k>0){
			x=k%2;
			a[i++]=x; //将二进制数全部存进数组中 
			k/=2;
		}
		for(int j=0; j<i; j++){
			if(a[j]==1) 
                            cout<<32-j; //判断何时从1开始,1后边的全是1,所以减去前边的0的个数 
		}
	} 
	return 0;
}

小结

核心还是进制转换问题,也要弄清楚正数和负数的原码如何转化为补码的过程。