题目描述
输入一个整数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。
思路
-
首先要明白,十进制转二进制核心:取模2、取余2、取模2、取余2...余数即为二进制数,且是倒着输出的,比如余数得到的为1101,但其二进制数表示应反过来,为1011。
-
若n>0,余数就是1,0的组合,将余数1存进数组中,最后输出数组个数即可。
-
若n<0,求的是补码,要负数的补码怎么转换:先讲负数变为正数,然后写出正数的二进制表示,从右向左开始,遇到的第一个1,接下来的数就全部都要变成1,这就是负数的补码。
-
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;
}
小结
核心还是进制转换问题,也要弄清楚正数和负数的原码如何转化为补码的过程。