行文脉络

  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 = ;
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的个数的更多相关文章

  1. 剑指Offer面试题:9.二进制中1的个数

    一.题目:二进制中1的个数 题目:请实现一个函数,输入一个整数,输出该数二进制表示中1的个数.例如把9表示成二进制是1001,有2位是1.因此如果输入9,该函数输出2. 二.可能引起死循环的解法 一个 ...

  2. 剑指Offer:二进制中1的个数

    题目:输入一个整数,输出该数二进制表示中1的个数. // 二进制中1的个数 #include <stdio.h> int wrong_count_1_bits(int n) // 错误解法 ...

  3. 1513:二进制中1的个数 @jobdu

    题目1513:二进制中1的个数 时间限制:1 秒 内存限制:128 兆 特殊判题:否 提交:1341 解决:455 题目描述: 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 输入: ...

  4. 基于visual Studio2013解决面试题之0410计算二进制中1的个数

     题目

  5. [PHP]算法-二进制中1的个数的PHP实现

    二进制中1的个数: 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 思路: 1.右移位运算>> 和 与运算& 2.先移位个然后再与1 &运算为1的就是1 ...

  6. 《剑指offer》 二进制中1的个数

    本题来自<剑指offer> 二进制中1的个数 题目: 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 思路: 两种思路: 第一种:对n进行左移,检测最后一位是否为1,但考 ...

  7. 剑指offer编程题Java实现——面试题10二进制中1的个数

    题目: 请实现一个函数,输入一个整数,输出该整数二进制表示中1的个数.例如,把9表示成二进制是1001,有2位是1,该函数输出2解法:把整数减一和原来的数做与运算,会把该整数二进制表示中的最低位的1变 ...

  8. leetcode 338. Counting Bits,剑指offer二进制中1的个数

    leetcode是求当前所有数的二进制中1的个数,剑指offer上是求某一个数二进制中1的个数 https://www.cnblogs.com/grandyang/p/5294255.html 第三种 ...

  9. 【Java】 剑指offer(14) 二进制中1的个数

    本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 请实现一个函数,输入一个整数,输出该数二进制表示中1的个数.例如把 ...

随机推荐

  1. 【转载】Ubuntu环境下安装QT(转)

    Ubuntu 安装 Qt 开发环境 简单实现是本文要介绍的内容,内容很短,取其精华,详细介绍Qt 类库的说明,先来看内容. 一.Ubuntu下安装Qt $ sudo apt-get install q ...

  2. WaitForSingleObject函数

    WaitForSingleObject函数 VC声明 DWORD WaitForSingleObject( HANDLE hHandle, DWORD dwMilliseconds ); VB声明 D ...

  3. JAVA之编码---->CSV在文本下是正常的,用EXCEL打开是乱码的问题

    JAVA之编码---->CSV在文本下是正常的,用EXCEL打开是乱码的问题 在JAVA下输出文件流,保存成CSV(用UTF-8)文件,怎么处理用EXCEL下是乱码,但是在记事本等其他软件都是正 ...

  4. 图像处理------Fuzzy C Means的聚合算法

    Fuzzy C-Means聚合算法在图像分割(segmentation)和图像视觉处理中常常被用到聚合算法之 一本文是完全基于JAVA语言实现Fuzzy C-Means聚合算法,并可以运用到图像处理中 ...

  5. MyEclipse完善提示配置

    MyEclipse完善提示配置 一般的,MyEclipse中的提示以"."后进行提示,不是很完善.现在,修改提示配置,让提示更完善! 具体操作如下: 1.打开MyEclipse,单 ...

  6. Caused by: java.lang.ClassNotFoundException: flex.messaging.io.BeanProxy

    1.错误描述 2014-7-13 1:34:46 org.apache.catalina.startup.HostConfig undeploy 信息: Undeploying context [/b ...

  7. freemarker字符串拼接(十二)

    freemarker字符串拼接 1.字符串拼接的几种类型 (1)字符串和字符串 (2)字符串和数字 (3)字符串和字符串变量 (4)字符串变量和字符串变量 2.演示示例 <#--定义字符串--& ...

  8. freemark标签从后台接过来数据Boolean在前台还是Boolean输出(四)

    FREEMARK标签中输出BOOLEAN值 private boolean showHeader=true; public boolean getShowHeader(){ return this.s ...

  9. Gedit : 我的开场白 [TPLY]

    为什么用Gedit 在学校的高一新生里,好像就只有我使用Gedit 大家都笑我是"用记事本编程的人" 我就想 到考场看看你们笑得出来不 先放一个高配emacs配置 (global- ...

  10. 【BZOJ4012】开店(主席树)

    [BZOJ4012]开店(主席树) 题面 Description 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱 ...