行文脉络

  1. 解法一——除法
  2. 解法二——移位
  3. 解法三——高效移位
  4. 解法四——查表
  5. 扩展问题——异或后转化为该问题

对于一个字节(8bit)的变量,求其二进制“1”的个数。例如6(二进制0000 0110)“1”的个数为2,要求算法效率尽量高。

解法一

对于二进制数来说,除一个2,就少一位,可以判断这个少的位来确定“1”的个数。

例如:6(0000 0110)

0000 0110 / 2 = 0000 0011     ----少的一位为0

0000 0011 / 2 = 0000 0001     ----少的一位为1

0000 0001 / 2 = 0000 0000     ----少的一位为1

操作数数已经为0,到此结束

参考代码

int Count_1(int val)
{int num = 0;while(val){if(val % 2 != 0)   //用取模获得去除的一位++num;val /= 2;}return num;
}

性能:时间复杂度O(log2v),即二进制数的位数;空间复杂度O(1)

解法二

对于二进制数来说,除法是用移位完成。

例如:6(0000 0110)

0000 0110 >> 1 = 0000 0011     ----少的一位为0

0000 0011 >> 1 = 0000 0001     ----少的一位为1

0000 0001 >> 1 = 0000 0000     ----少的一位为1

操作数数已经为0,到此结束

参考代码

int Count_2(int val)
{int num = 0;while(val){if(val & 1 != 0)   //用与1与获得移除的一位++num;val >>= 1;}return num;
}

性能:时间复杂度O(log2v),即二进制数的位数;空间复杂度O(1)

解法三

对于上述算法,有个问题,比如1000 0000,大把的时间用在没用的0上,最好寻求一种直接判断“1的个数。

通过观察可以找到规律:对于数a, a = a & (a-1)就可以去除a的最后一个1

例如:6(0000 0110)

0000 0110 & 0000 0101 = 0000 0100

0000 0100 & 0000 0011 = 0000 0000

操作数数已经为0,到此结束

参考代码

int Count_3(int val)
{int num = 0;while(val){val &= (val -1);++num;}return num;
}

性能:时间复杂度O(M),即二进制中“1”的个数,空间复杂度O(1)

解法四

查表法,把0~255这256个数的结果全部存储在数组中,val直接作为下标,countTable[val]即为结果。典型的用空间换时间。

参考代码

int Count_5(int val)
{int countTable[] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8};return countTable[val];
}

性能:时间复杂度:O(1), 空间复杂度O(N)

整个程序执行参考

#include<iostream>
using namespace std;int Count_1(int val)
{int num = 0;while(val){if(val % 2 != 0)++num;val /= 2;}return num;
}int Count_2(int val)
{int num = 0;while(val){if(val & 1 != 0)++num;val >>= 1;}return num;
}int Count_3(int val)
{int num = 0;while(val){val &= (val -1);++num;}return num;
}
int Count_5(int val)
{int countTable[] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8};return countTable[val];
}int main()
{int a = 6, b = 255;cout << "Num of 1:" << Count_1(a) << endl; cout << "Num of 1:" << Count_2(a) << endl; cout << "Num of 1:" << Count_3(a) << endl; cout << "Num of 1:" << Count_5(b) << endl; cout << "Num of 1:" << Count_1(b) << endl; cout << "Num of 1:" << Count_2(b) << endl; cout << "Num of 1:" << Count_3(b) << endl; cout << "Num of 1:" << Count_5(b) << endl;
}

View Code

结果

扩展问题

1. 给定两个正整数(二进制表示)A、B,如何快速找出A和B二进制表示中不同位数的个数。

  思路

  首先A和B进行异或操作,然后求得到的结果中1的个数(此问题)。

2. 判断一个数是否是2的幂

bool powerof2(int n)
{return ((n & (n-1)) == 0);
}

转载于:https://www.cnblogs.com/kaituorensheng/p/3562076.html

求二进制中1的个数(编程之美2.1)相关推荐

  1. 编程之美2.1 求二进制中1的个数

    最近一段的时间,一直在看编程之美之类的算法书籍,刚开始看编程之美,感觉到难度太大,有时候也不愿意去翻动这本书,不过,经过一段时间的修炼,我也彻底的喜欢上这本书了, 书中的算法涉及到很多方面,树,链表, ...

  2. 第2章 数字之魅——求二进制中1的个数

    求二进制中1的个数 问题描述 对于一个字节(8bit)的变量,求其二进制表示中"1"的个数,要求算法的执行效率尽可能地高. [解法一] 可以举一个八位的二进制例子来进行分析.对于二 ...

  3. 不使用循环,求二进制中1的个数

    对于2位的二进制数,求其中1的个数.有一个奇妙的算法. (设X , y,z 代表二进制中一位比特位的值)(>>右移,&按位与(都为1才为1)) 已知 i (X1 X2),j = ( ...

  4. 编程之美 2.1 求二进制中1的个数

    问题描述: 对于1个字节(8bit)无符号整型变量,求其二进制表示中"1"的个数 解法一:除2取余 (对于二进制操作,除以一个2,原来的数字会减少一个0.如果除的过程中有余数,就表 ...

  5. 【算法】布赖恩·克尼根算法——天才算法求二进制中1的个数

    题目背景 做leetcode第461题汉明距离的时候,发现一个很骚的求1的个数的算法,大呼牛逼! 其实题目本身思路不难,就是求异或然后算1个个数,只是没有想到还可以用这么骚的方式来求. 布赖恩·克尼根 ...

  6. 【博客177】二进制中1的个数:方法三

    内容: 记录求二进制中1的个数的另一种好方法:汉明重量计算算法 最近在看redis源码,发现redis求二进制中1的个数的方法很赞,记录一下: 代码: int vpSWAR(int i) {i = ( ...

  7. 说一说,求一个正整数的二进制中0的个数

    昨天突然看到一个算法题:一个正整数a的二进制中0的个数: 话说这是个老题了,直观的算法就每次右移一位,直到0为止:代码就省略了: 仔细想想有更好的方案么? 就是这个题可以转换成一个正整数~a的二进制中 ...

  8. C/C++求一个整数的二进制中1的个数

    求一个整数的二进制中1的个数 收藏 题目:输入一个整数,求该整数的二进制表达中有多少个1.例如输入10,由于其二进制表示为1010,有两个1,因此输出2. 分析:这是一道很基本的考查位运算的面试题.包 ...

  9. 05-04 求负数二进制中1的个数

    # 求整数二进制中1的个数? # 若整数为整数,直接求二进制,将其转为str遍历判断是否1, # 若为负数,求其补码,再解题, 问:整数二进制指的补码还是原码?def count1(n):print( ...

最新文章

  1. 紧随时代发展 安防消费也在悄然发生改变
  2. 【组原】广州大学计算机组成原理考试部分题+复习资料(2020-2021)
  3. vue组件的基本使用:入门示例
  4. spring注入普通java类_普通java类如何取得注入spring Ioc容器的对象
  5. (转载)在IAR及MDK里生成hex及bin文件的标准方法
  6. vue 地图使用navigator_9 个实验 + 3 个项目,带你入门 Vue.js 3 !
  7. scheme中文编程
  8. matlab 求正交补,机器人动力学(一)空间向量(Spatial Vectors)简介
  9. 迁安职中计算机专业,迁安职业技术教育中心2021年招生简章
  10. 使用py 和flask 实现的服务器系统目录浏览,日志文件实时显示到网页的功能
  11. java 分布式 定时任务_Java中实现分布式定时任务的方法
  12. 锐浪报表-实现导入导出
  13. 在iPhone设置一个快捷指令,一键将PDF转为图片
  14. [Shell命令] tar -cvf -xvf 打包解包文件夹
  15. 获取高程数据并生成等高线
  16. SLAM中双目三角化
  17. PaddlePaddle飞浆搭建和机器学习文字识别
  18. STM32—DAC配置
  19. I - Modulo Permutations (SEERC 2020)
  20. Jack Server--Android N AOSP编译--Failed to contact Jack server

热门文章

  1. 2022-2028年中国顺丁橡胶行业发展模式分析及市场分析预测报告
  2. HTTP服务器端常用推送技术
  3. 阿里云Centos 解决挖矿程序:kdevtmpfsi--服务器CPU占用高、内存占用高
  4. Adam那么棒,为什么还对SGD念念不忘 (1) —— 一个框架看懂优化算法
  5. 初学MyBatis-Plus
  6. LeetCode简单题之最小操作次数使数组元素相等
  7. LeetCode简单题之移动零
  8. Hexo集成Valine实现评论留言
  9. MLIR算子量化Quantization
  10. 稀疏性如何为AI推理增加难度