【11】二进制中1的个数
- 时间限制:1秒
- 空间限制:32768K
题目描述
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
牛客网题目链接:点击这里
思路:从4位演示
机器码 | 有符号 | 无符号 | 机器码 | 有符号 | 无符号 |
---|---|---|---|---|---|
0000 | 0 | 0 | 1000 | 8 | -8 |
0001 | 1 | 1 | 1001 | 9 | -7 |
0010 | 2 | 2 | 1010 | 10 | -6 |
0011 | 3 | 3 | 1010 | 11 | -5 |
0100 | 4 | 4 | 1010 | 12 | -4 |
0101 | 5 | 5 | 1010 | 13 | -3 |
0110 | 6 | 6 | 1010 | 14 | -2 |
0111 | 7 | 7 | 1010 | 15 | -1 |
- 在有符号中,第一位为符号为,0表示正,1表示负.
- 4位从-8~7;8位从-16~15;16位从-256~255;32位从-65536~65535;
- 补码=原码的反码+1;
- -6:原码0110,反码1001,补码1010.
- 因此,在机器中,4位的-6和10机器码是一样的。
vs2010代码:
#include<iostream>
using namespace std;
class Solution {
public:
int NumberOf1(int n) {
if(n==0) return 0;
if(n>0)
{
int Num=0;
while(n!=0)
{
if(n%2==1) Num++;
n=n/2;
}
return Num;
}
else
{
unsigned int N;
N=(unsigned int)n;
int Num=0;
while(N!=0)
{
if(N%2==1) Num++;
N=N/2;
}
return Num;
}
}
};
int main()
{
Solution S1;
int n=0;
while(1)
{
cin>>n;
cout<<S1.NumberOf1(n);
cout<<endl;
}
}
方法二:
敌动我不动,最后一位的决定权交给n
class Solution {
public:
int NumberOf1(int n) {
if(n==0) return 0;
//我动敌不动
if(n>0)
{
int Num=0;
while(n)
{
if(n&1) Num++;
n=n>>1;
}
return Num;
}
else
{
unsigned int N;
N=(unsigned int)n;
int Num=0;
while(N!=0)
{
if(N%2==1) Num++;
N=N/2;
}
return Num;
}
}
};
方法三:
我动敌不动,避免为负数时进入死循环
class Solution {
public:
int NumberOf1(int n) {
int Num=0;
unsigned int flag=1;
while(flag)
{
if(n&flag) Num++;
flag=flag<<1;
}
return Num;
}
};
方法四:把一个整数减去1,都是最右边的1变成0.
class Solution {
public:
int NumberOf1(int n) {
int Num=0;
while(n)
{
Num++;
n=n&(n-1);
}
return Num;
}
};
总结:把一个整数减去1之后再和原来的整数做位与运算,得到的结果相当于是把整数的二进制表示中的最右边一个1变成0.