题目:
请实现一个函数,输入一个整数,输出该数二进制表示中1的个数。例如把9表示成二进制是1001,有2位是1.因此如果输入9,该函数输出2.
方法一:
注意:整数和负数以及0的区别,这是由存储机制决定的。
分析:将输入的整数依次右移并与1相位与!
源代码如下:
#include<iostream>
using std::cout;
using std::endl;
using std::cin;
int NumberOfOne1(long long n)
{
if (0 == n)
return 0;
long long unsigned num = 0;
if (n < 0)
num = n*(-1);
else
num = n;
int result = 0;
while (num != 0)
{
if (num & 1)
result++;
num = num >> 1;
}
if (n > 0)
return result;
else
return result + 1;
}
int main1()
{
for (int i = 0; i < 5; i++)
{
cout << "请输入十进制整数n:";
int n;
cin >> n;
cout << "十进制整数" << n << "中二进制表示中1的个数为:" << NumberOfOne1(n) << endl;
}
system("pause");
return 0;
}
请输入十进制整数n:63
十进制整数63中二进制表示中1的个数为:6
请输入十进制整数n:-63
十进制整数-63中二进制表示中1的个数为:7
请输入十进制整数n:255
十进制整数255中二进制表示中1的个数为:8
请输入十进制整数n:-255
十进制整数-255中二进制表示中1的个数为:9
请输入十进制整数n:10
十进制整数10中二进制表示中1的个数为:2
请按任意键继续. . .
方法二:
上述方法直接移动整数,且可以处理输入负整数的情况,接下来我们移动标志位保持输入的整数不变!
源代码如下(十六进制输入方式):
#include<iostream>
using std::cout;
using std::cin;
using std::endl;
int NumberOfOne2(int n)
{
unsigned int flag = 1;
int result = 0;
while (flag)
{
if (flag & n)
result++;
flag = flag << 1;
}
return result;
}
int main()
{
for (int i = 0; i < 5; i++)
{
int n = 0;
cout << "请输入十进制数n:";
cin >> std::hex >> n;
cout << "十进制数" << n << "的二进制表示中1的个数为:" << NumberOfOne2(n) << endl;
}
system("pause");
return 0;
}
运行结果:
请输入十进制数n:0x1
十进制数1的二进制表示中1的个数为:1
请输入十进制数n:0x8000
十进制数32768的二进制表示中1的个数为:1
请输入十进制数n:0x9
十进制数9的二进制表示中1的个数为:2
请输入十进制数n:0xff
十进制数255的二进制表示中1的个数为:8
请输入十进制数n:0x1ff
十进制数511的二进制表示中1的个数为:9
请按任意键继续. . .
源代码(十进制):
#include<iostream>
using std::cout;
using std::cin;
using std::endl;
/*
负数在内存中是以补码的形式存储的,所以这种算法对于直接输入负整数时,计算是错误的!!!
负数的输入应采取十六进制的输入形式
*/
int NumberOfOne2(int n)
{
unsigned int flag = 1;
int result = 0;
while (flag)
{
if (flag & n)
result++;
flag = flag << 1;
}
return result;
}
int main()
{
for (int i = 0; i < 5; i++)
{
int n = 0;
cout << "请输入十进制数n:";
cin >> n;
cout << "十进制数" << n << "的二进制表示中1的个数为:" << NumberOfOne2(n) << endl;
}
system("pause");
return 0;
}
请输入十进制数n:9
十进制数9的二进制表示中1的个数为:2
请输入十进制数n:-9
十进制数-9的二进制表示中1的个数为:31
请输入十进制数n:255
十进制数255的二进制表示中1的个数为:8
请输入十进制数n:-255
十进制数-255的二进制表示中1的个数为:25
请输入十进制数n:63
十进制数63的二进制表示中1的个数为:6
请按任意键继续. . .
方法三:
把一个整数减去1,再和原来的整数做与运算,会把该整数最右边一个1变成0,那个一个整数的二进制表示中有多少个1,就可以进行多少次这样的操作。
源代码:
#include<iostream>
using std::cout;
using std::endl;
using std::cin;
/*
负数在内存中是以补码的形式存储的,所以这种算法对于直接输入负整数时,计算是错误的!!!
负数的输入应采取十六进制的输入形式
*/
int NumberOfOne3(int n)
{
int result = 0;
while (n)
{
n = n&(n - 1);
result++;
}
return result;
}
int main()
{
for (int i = 0; i < 5; i++)
{
int n;
cout << "请输入整数n" << endl;
cin >> n;
cout << "十进制数" << n << "的二进制表示中1的个数为:" << NumberOfOne3(n) << endl;
}
system("pause");
return 0;
}
运行结果和方法二相似。
官方源代码:
#include<stdio.h>
#include<stdlib.h>
int NumberOf1_Solution1(int n)
{
int count = 0;
unsigned int flag = 1;
while (flag)
{
if (n & flag)
count++;
flag = flag << 1;
}
return count;
}
int NumberOf1_Solution2(int n)
{
int count = 0;
while (n)
{
++count;
n = (n - 1) & n;
}
return count;
}
void Test(int number, unsigned int expected)
{
int actual = NumberOf1_Solution1(number);
if (actual == expected)
printf("Solution1: Test for %p passed.\n", number);
else
printf("Solution1: Test for %p failed.\n", number);
actual = NumberOf1_Solution2(number);
if (actual == expected)
printf("Solution2: Test for %p passed.\n", number);
else
printf("Solution2: Test for %p failed.\n", number);
printf("\n");
}
int main()
{
// 输入0,期待的输出是0
Test(0, 0);
// 输入1,期待的输出是1
Test(1, 1);
// 输入10,期待的输出是2
Test(10, 2);
printf("新加\n");
Test(-9, 3);
// 输入0x7FFFFFFF,期待的输出是31
Test(0x7FFFFFFF, 31);
// 输入0xFFFFFFFF(负数),期待的输出是32
Test(0xFFFFFFFF, 32);
// 输入0x80000000(负数),期待的输出是1
Test(0x80000000, 1);
system("pause");
return 0;
}
运行结果:
Solution1: Test for 00000000 passed.
Solution2: Test for 00000000 passed.
Solution1: Test for 00000001 passed.
Solution2: Test for 00000001 passed.
Solution1: Test for 0000000A passed.
Solution2: Test for 0000000A passed.
新加
Solution1: Test for FFFFFFF7 failed.
Solution2: Test for FFFFFFF7 failed.
Solution1: Test for 7FFFFFFF passed.
Solution2: Test for 7FFFFFFF passed.
Solution1: Test for FFFFFFFF passed.
Solution2: Test for FFFFFFFF passed.
Solution1: Test for 80000000 passed.
Solution2: Test for 80000000 passed.
请按任意键继续. . .