该问题是经典面试题目,有多种解法,这里选取两种解法。
解法1:时间复杂度O(log2v)
解法2:时间复杂度O(m),其中m是1的个数
这里对解法2做个解释。
举例:加入二进制数中只有一个1
01000000
01000000&(01000000-00000001)=01000000&00111111=0
贴代码:
/*
统计一个字节8位的二进制数中1的个数
*/
#include <iostream>
#include<Windows.h>
using namespace std;
int flag = 0;
//解法1:
//void count(byte v)
//{
// while (v)
// {
// if (v % 2 == 1)
// flag++;
// v = v / 2;
// }
// cout << flag << endl;
//}
//解法2
void count(byte v)
{
while (v)
{
//清楚最低位1
v = v&(v - 1);
flag++;
}
cout << flag << endl;
}
int main()
{
count(27); //00011011 0x1b 0x1a 0x18 0x10 0x0
system("pause");
return 0;
}
拓展:给定两个二进制数AB,把A编程B需要更改多少位,即找出AB二进制位不同位数
思路:对AB进行异或操作,二进制数相同为0不同为1,再统计异或结果1的个数即可
举例:6 A: 00000110
27 B :00011011
C: 00011101
/*
统计一个字节8位的二进制数中1的个数
*/
#include <iostream>
using namespace std;
int flag = 0;
//统计1的个数,int类型,32位二进制
void count(int v)
{
while (v)
{
v = v&(v - 1);
flag++;
}
cout << flag << endl;
}
//异或,相同为0不同为1,异或后再统计1的个数即可
void compAB(int a, int b)
{
int c = a^b;
count(c);
}
int main()
{
compAB(6, 27);
system("pause");
return 0;
}