该问题是经典面试题目,有多种解法,这里选取两种解法。
解法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; }