首页 > 代码库 > 剑指Offer:二进制中1的个数
剑指Offer:二进制中1的个数
题目:输入一个整数,输出该数二进制表示中1的个数。
// 二进制中1的个数#include <stdio.h>int wrong_count_1_bits(int n) // 错误解法: 当n为负数时, n>>=1右移, 最高位补1, 陷入死循环{ int count = 0; while(n) { if( n & 1 ) ++count; n >>= 1; } return count;}int count_1_bits(int n) // 常规解法, 若sizeof(int)=4, 循环32次{ unsigned int mask = 1; int count = 0; while(mask) // 循环32次后, mask变为0 { if( mask & n ) ++count; mask <<= 1; } return count;}int perfect_count_1_bits(int n) // 高效解法, 若n含二进制位为1的位数为t, 则循环t次{ int count = 0; while(n) { n = (n-1) & n; // 执行该语句后, n的二进制表示中, 最右边的1被置为0, 其余各位不变, 也即是每循环一次, 消去n最靠右的1 ++count; } return count;}int static_table_count_1_bits(int n) // 静态表法{ int table[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 }; int count =0 ; while (n) { count += table[n &0xf] ; n >>=4 ; } return count ;}int main(void){ printf("sizeof(int)=%d\n",sizeof(int)); printf("%d\n",0x0fffff73); // 非负数正常; 负数(如0xffffff73)会导致程序在wrong_count_1_bits函数处陷入死循环 int count1 = count_1_bits(0x0fffff73); int count2 = perfect_count_1_bits(0x0fffff73); int count3 = wrong_count_1_bits(0x0fffff73); int count4 = static_table_count_1_bits(0x0fffff73); printf("count1=%d,count2=%d,count3=%d,count4=%d\n",count1,count2,count3,count4); return 0;}
关键点:把一个整数减去1之后再和原来的整数做按位与运算& ,得到的结果相当于把整数的二进制表示中的最右边一个1变成0。
相关题目1:用一条语句判断一个整数是不是2的整数次方
if( (n-1)&n == 0 ) printf("Yes\n");
相关题目2:输入两个整数m和n,计算需要改变m的二进制表示中的多少位才能得到n。
步骤1:求这两个数的异或 t = m^n;
步骤2:统计异或结果t的二进制表示中1的个数,即为需要改变的位数。
相关题目3:二进制中0的个数
方法1:上面常规解法中,改成 if( n^mask == 1 ) ++count;
方法2:先使用上面某种方法求得“二进制中1的个数”,间接求解:sizeof(int)*8 - 1的个数
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。