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. Connection.setAutoCommit使用的注意事项

    http://blog.csdn.net/xiayimiaokuaile/article/details/6422032 setAutoCommit总的来说就是保持数据的完整性,一个系统的更新操作可能 ...

  2. Zabbix linux agent 安装

    系统:Linux Centos 7.3 x64 服务:Zabbix_agent 3.0.16 一.安装Zabbix_agent 服务 1.安装zabbix 3.0 yum源 rpm -ivh http ...

  3. MySQL java连接被拒绝:java.sql.SQLException: Access denied for user 'root'@'****' (using password: YES)

    //系统运行出现错误:java.sql.SQLException: Access denied for user 'root'@'***.**.**.**' (using password: YES) ...

  4. [mongodb] MMAPv1 Storage Engine

    MMAPv1 是mongodb 在3.2以前默认的存储引擎,在3.2 之后默认的存储引擎为WiredTiger,MMAPv1存储引擎基于内存映射文件,它擅长高容量的插入,读取和更新. Journal ...

  5. 采用DoGet方式提交中文,乱码产生原因分析及解决办法

    前段时间某功能在测试机器上出现乱码,情况如下:   现象:           调试搜索功能时,通过doGet方法提交到后台的中文参数在本地和开发测试机器上为乱码(Action层),在测试人员测试机器 ...

  6. select 下拉框 设置值

    function setSelectOption(objSelect, targetValue){ if(objSelect){ var options = objSelect.options; if ...

  7. jsp基础知识点——思维导图

    如图 思维导图图片链接 http://www.edrawsoft.cn/viewer/public/s/0b8cd083478732 有道云笔记图片链接 http://note.youdao.com/ ...

  8. Struts2小例子

    第一个Struts 2.0例子 工具:MyEclipse 6.0.1 第一步:新建web project 第二步:为项目加入Struts 2.0 的jar包 官方下载地址:http://struts. ...

  9. Treflection05_扩展习题

    1. package reflectionZ; import java.lang.reflect.Constructor; import java.lang.reflect.Method; publi ...

  10. Angularjs注入拦截器实现Loading效果

    angularjs作为一个全ajax的框架,对于请求,如果页面上不做任何操作的话,在结果烦回来之前,页面是没有任何响应的,不像普通的HTTP请求,会有进度条之类. 什么是拦截器? $httpProvi ...