32位二进制里有多少个1

https://blog.csdn.net/zhangsj1007/article/details/81411063

有这样一道计算机问题“32位二进制里面有多少个1”。这是一道比较普遍也比较简单的计算机题目,但是之前看过一篇文章,不单单是答案,而是在各个方面对该问题做了考虑。看了之后,很受启发,现在把这篇文章整理一下。

简单明了的方法

         最简单明了的方法,就是遍历一遍这个32位的数字的各个二进制位,然后数一数1的个数。

s & (s-1)

        因为计算机是二进制存储数据,基于这种存储方式,我们可以把任何一个数字看成是若干个2的n次方的和的形式。例如:10010011表示147,它等于2的7次方+2的4次方+2的1次方+2的0次方。又由于对于任何一个2的n次方的数字s,例如128=10000000,s-1=01111111,可以看到s&(s-1)可以消灭掉s中的最低位的1。而对于一个有若干个2的n次方和的s,只要进行若干次这样的操作,就会使得s最终等于0。所以,算法如下:

int cnt = 0;
while (s != 0){
s = s & (s - 1);
cnt++;
}
return cnt;

算法很简单,也很好理解,这样s中有几个1,就进行几次上述的操作。

查表法

        我们还可以运用查表法,查表法是在节省时间的基础上以使用更多的物理资源为代价。如果是32位数,则需要4GB的存储空间。这样对于任何一个32位的数字,只要进行一次查表法即可获得答案,也大大节省了效率。

那么能否在时间效率和存储效率做一个权衡那?我们可以将32位数字拆解成两组16位的数字,这样需要进行2次查表,但是所消耗的内存却从4GB减少到64KB,这个时候需要2次查表加1次加法运算,需要3步操作。如果将32位数字拆解成四组8位的数字,所消耗的内存继续减少为256个字节,这样需要进行4次查表,这个时候需要4次查表加3次加法运算,需要7步操作。

那么是否一定用一张4GB的大表比用一张64KB或者256字节的小表来的快那?从理论上来讲,1次查表操作,要比3次操作或是7次操作来的快。但是在真实的计算机系统中,主存与CPU之间有一个高速缓存。高速缓存的空间有限,通常只有几兆,4G内存的空间容量是高速缓存的上千倍。这样在进行随机测试的时候,可能每一次查表都需要从主存中把数据拷贝到缓存中,而一次cache miss的时间,CPU可以进行几百次的时钟操作。这样看来,实际上使用小表其实更加提升效率。

参考文献:

1.《吴军的谷歌方法论》

作者:Happy_Traveller

来源:CSDN

原文:https://blog.csdn.net/zhangsj1007/article/details/81411063?utm_source=copy

版权声明:本文为博主原创文章,转载请附上博文链接!

N位N进制里有多少个N的更多相关文章

  1. CF459C Pashmak and Buses (构造d位k进制数

    C - Pashmak and Buses Codeforces Round #261 (Div. 2) C. Pashmak and Buses time limit per test 1 seco ...

  2. C# 颜色有3种表示方式: 6位16进制、RGB、 颜色关键字

    最常用的是6位16进制的代码表示法.如bgcolor=#ff0000;其中#只是表示使用6位16进制的颜色代码声明颜色.代码的头两位即ff表示三原色中的红色,范围当然是16进制的00-ff,中间两位即 ...

  3. 通过递归遍历n位2进制数的所有情况

    题目要求: 输入一个正整数m,输出m位2进制的所有取值情况,从小到大输出,每个输出结果用换行符分割. 解题思路: 通过递归调用,从第1个到第m个数组元素分别置0和置1,然后当从1到m所有的元素都置0或 ...

  4. 汇编:1位16进制数到ASCII码转换

    ;============================ ;1位16进制数到ASCII码转换 ; { X+30H (0≤X≤9) ;Y= { ; { X+37H (0AH≤X≤0FH) DATAS ...

  5. [转]as3 算法实例【输出1 到最大的N 位数 题目:输入数字n,按顺序输出从1 最大的n 位10 进制数。比如输入3,则输出1、2、3 一直到最大的3 位数即999。】

    思路:如果我们在数字前面补0的话,就会发现n位所有10进制数其实就是n个从0到9的全排列.也就是说,我们把数字的每一位都从0到9排列一遍,就得到了所有的10进制数. /** *ch 存放数字 *n n ...

  6. 2~62位任意进制转换(c++)

    进制转换的符号表为[0-9a-zA-Z],共61个字符,最大可表示62进制. 思路是原进制先转换为10进制,再转换到目标进制. 疑问: 对于负数,有小伙伴说可以直接将符号丢弃,按照整数进行进位转换,最 ...

  7. 为什么分库分表使用2的N次方 一个字节用两位16进制

    你说说为神马表的总数.redis库的总数.HashMap的数量最好是2的N次方 数据在表库HashMap 落地时候都会跟总数取模,这个我们做个测试 假设数量是2的3次方就是8,即索引就是0-7 php ...

  8. 位运算 进制转化 STL中bitset用法

    2017-08-17 16:27:29 writer:pprp /* 题目名称:输入十进制以二进制显示 程序说明:同上 作者:pprp 备注:无 日期:2017/8/17 */ #include &l ...

  9. md5加密--32位16进制小写

    public class ttgameMd5 { public final static String MD5(String str) { char hexDigits[] = { // 用来将字节转 ...

随机推荐

  1. HDU4639

    /*计算里面有多少个相邻的he,1个he就是1种意思,两个就是,两种,所以这是 一个斐波拉期数列,间隔的hehe互不影响所以是互斥事件,直接相乘就可以*/ #include<stdio.h> ...

  2. HCNP学习笔记之TCP中FLAGS字段SYN, FIN, ACK, PSH, RST, URG

    在TCP层,有个FLAGS字段,这个字段有以下几个标识:SYN, FIN, ACK, PSH, RST, URG. 其中,对于我们日常的分析有用的就是前面的五个字段. 含义: SYN 表示建立连接, ...

  3. div 文章内容自动分屏显示

    <head runat="server"> <title></title> <script language="javascri ...

  4. Linux下解压分包文件zip(zip/z01/z02)【转】

    本文转载自:https://www.cnblogs.com/EasonJim/p/7227109.html?utm_source=itdadao&utm_medium=referral Lin ...

  5. SpringBoot 悲观锁 与 乐观锁

    乐观所和悲观锁策略 悲观锁:在读取数据时锁住那几行,其他对这几行的更新需要等到悲观锁结束时才能继续 . 乐观所:读取数据时不锁,更新时检查是否数据已经被更新过,如果是则取消当前更新,一般在悲观锁的等待 ...

  6. 数据结构(二) 树Tree

    五.树 树的定义   树的逻辑表示:树形表示法.文氏图表示法.凹入表示法.括号表示法.         结点:表示树中的元素,包括数据项及若干指向其子树的分支. 结点的度:结点拥有的子树树:树的度:一 ...

  7. iOS日常学习 - 让你的 Xcode8 继续使用插件

    本文转载,原文链接 随着 iOS10 的正式版即将发布,Xcode8 GM 也在发布会后放出,本文不会涉及到 Xcode8 有哪些更新,而是记录了如何让 Xcode8 继续支持 Plugin. 相信各 ...

  8. LeetCode——Number of Boomerangs

    LeetCode--Number of Boomerangs Question Given n points in the plane that are all pairwise distinct, ...

  9. DEV控件的Gridview小技巧总结

    1.设置Gridview控件的某列不可编辑 this.gridData.gridView1.Columns["change_date"].OptionsColumn.AllowEd ...

  10. 判断浏览器是否支持某一个CSS3属性

    判断浏览器是否支持某一个CSS3属性 function supportCss3(style) { var prefix = ['webkit', 'Moz', 'ms', 'o'], i, humpS ...