Algorithm --> 二进制中1的个数
行文脉络
- 解法一——除法
- 解法二——移位
- 解法三——高效移位
- 解法四——查表
- 扩展问题——异或后转化为该问题
对于一个字节(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 = ;
while(val)
{
if(val % != ) //用取模获得去除的一位
++num;
val /= ;
}
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 = ;
while(val)
{
if(val & != ) //用与1与获得移除的一位
++num;
val >>= ;
}
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 = ;
while(val)
{
val &= (val -);
++num;
}
return num;
}
性能:时间复杂度O(M),即二进制中“1”的个数,空间复杂度O(1)
解法四
查表法,把0~255这256个数的结果全部存储在数组中,val直接作为下标,countTable[val]即为结果。典型的用空间换时间。
参考代码
int Count_5(int val)
{
int countTable[] = {, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , };
return countTable[val];
}
性能:时间复杂度:O(1), 空间复杂度O(N)
整个程序执行参考
#include<iostream>
using namespace std; int Count_1(int val)
{
int num = ;
while(val)
{
if(val % != )
++num;
val /= ;
}
return num;
} int Count_2(int val)
{
int num = ;
while(val)
{
if(val & != )
++num;
val >>= ;
}
return num;
} int Count_3(int val)
{
int num = ;
while(val)
{
val &= (val -);
++num;
}
return num;
}
int Count_5(int val)
{
int countTable[] = {, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , };
return countTable[val];
} int main()
{
int a = , b = ;
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;
}
结果

扩展问题
1. 给定两个正整数(二进制表示)A、B,如何快速找出A和B二进制表示中不同位数的个数。
思路
首先A和B进行异或操作,然后求得到的结果中1的个数(此问题)。
2. 判断一个数是否是2的幂
bool powerof2(int n)
{
return ((n & (n-)) == );
}
Algorithm --> 二进制中1的个数的更多相关文章
- 剑指Offer面试题:9.二进制中1的个数
一.题目:二进制中1的个数 题目:请实现一个函数,输入一个整数,输出该数二进制表示中1的个数.例如把9表示成二进制是1001,有2位是1.因此如果输入9,该函数输出2. 二.可能引起死循环的解法 一个 ...
- 剑指Offer:二进制中1的个数
题目:输入一个整数,输出该数二进制表示中1的个数. // 二进制中1的个数 #include <stdio.h> int wrong_count_1_bits(int n) // 错误解法 ...
- 1513:二进制中1的个数 @jobdu
题目1513:二进制中1的个数 时间限制:1 秒 内存限制:128 兆 特殊判题:否 提交:1341 解决:455 题目描述: 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 输入: ...
- 基于visual Studio2013解决面试题之0410计算二进制中1的个数
题目
- [PHP]算法-二进制中1的个数的PHP实现
二进制中1的个数: 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 思路: 1.右移位运算>> 和 与运算& 2.先移位个然后再与1 &运算为1的就是1 ...
- 《剑指offer》 二进制中1的个数
本题来自<剑指offer> 二进制中1的个数 题目: 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 思路: 两种思路: 第一种:对n进行左移,检测最后一位是否为1,但考 ...
- 剑指offer编程题Java实现——面试题10二进制中1的个数
题目: 请实现一个函数,输入一个整数,输出该整数二进制表示中1的个数.例如,把9表示成二进制是1001,有2位是1,该函数输出2解法:把整数减一和原来的数做与运算,会把该整数二进制表示中的最低位的1变 ...
- leetcode 338. Counting Bits,剑指offer二进制中1的个数
leetcode是求当前所有数的二进制中1的个数,剑指offer上是求某一个数二进制中1的个数 https://www.cnblogs.com/grandyang/p/5294255.html 第三种 ...
- 【Java】 剑指offer(14) 二进制中1的个数
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 请实现一个函数,输入一个整数,输出该数二进制表示中1的个数.例如把 ...
随机推荐
- TI Davinci DM6446开发攻略——根文件系统的裁剪和移植
一.补充文件系统知识 Linux根文件系统是存放tool软件.lib文件.script(脚本).配置文件.其他特殊文件.自己开发的应用程序的地方.嵌入式linux的根文件系统rootfs就像windo ...
- 讨论MMU
MMU是Memory Management Unit的缩写,中文名是内存管理单元,它是中央处理器(CPU)中用来管理虚拟存储器.物理存储器的控制线路,同时也负责虚拟地址映射为物理地址,以及提供硬件机制 ...
- CentOS中配置NFS服务
1.服务器端安装rpcbind.nfs-utils.nfs-server包 yum install nfs-utils -y 2.修改服务器端配置文件,添加需要共享的文件夹. vim /etc/exp ...
- Carries SCU - 4437
Carries frog has nn integers a1,a2,-,ana1,a2,-,an, and she wants to add them pairwise. Unfortunately ...
- 复制粘贴之插件(clipboard.min.js)不需要安装flash
<!DOCTYPE html> <html> <head> <title>ZeroClipboard Test</title> <me ...
- 零基础新手学习Java必须知道的市场行情
Java如今的市场不如从前,竞争很大,工资非常高,标准非常高,想要胜任一份高薪的工作不是那么容易,只有掌握最新的行情才能更好的了解Java,才能更好的在这个领取发展,让新手小白了解Java市场行情如下 ...
- 【BZOJ1189】紧急疏散(二分答案,最大流)
[BZOJ1189]紧急疏散(二分答案,最大流) 题面 Description 发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域.每个格子如果是'.',那么表示这是一块空地:如果是 ...
- [BZOJ3293] [Cqoi2011] 分金币 (贪心)
Description 圆桌上坐着n个人,每人有一定数量的金币,金币总数能被n整除.每个人可以给他左右相邻的人一些金币,最终使得每个人的金币数目相等.你的任务是求出被转手的金币数量的最小值. Inpu ...
- IE浏览器右键菜单插件开发(下篇)——如何用c#安装、卸载IE右键插件
建立Installer安装类,如图: 代码如下: using Microsoft.Win32; using ResourceShare.UserClient.Common; using System; ...
- 树莓派centos安装的基本配置
萌新再发一帖,这篇文章呢主要是为大家在树莓派上安装centos以后提供一个问题的解决方案. 首先我呢觉得好奇就在某宝上花了两百来块钱买了一套树莓派,很多人喜欢在树莓派上安装Debian,我呢更青睐用R ...