N位N进制里有多少个N
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的更多相关文章
- 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 ...
- C# 颜色有3种表示方式: 6位16进制、RGB、 颜色关键字
最常用的是6位16进制的代码表示法.如bgcolor=#ff0000;其中#只是表示使用6位16进制的颜色代码声明颜色.代码的头两位即ff表示三原色中的红色,范围当然是16进制的00-ff,中间两位即 ...
- 通过递归遍历n位2进制数的所有情况
题目要求: 输入一个正整数m,输出m位2进制的所有取值情况,从小到大输出,每个输出结果用换行符分割. 解题思路: 通过递归调用,从第1个到第m个数组元素分别置0和置1,然后当从1到m所有的元素都置0或 ...
- 汇编:1位16进制数到ASCII码转换
;============================ ;1位16进制数到ASCII码转换 ; { X+30H (0≤X≤9) ;Y= { ; { X+37H (0AH≤X≤0FH) DATAS ...
- [转]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 ...
- 2~62位任意进制转换(c++)
进制转换的符号表为[0-9a-zA-Z],共61个字符,最大可表示62进制. 思路是原进制先转换为10进制,再转换到目标进制. 疑问: 对于负数,有小伙伴说可以直接将符号丢弃,按照整数进行进位转换,最 ...
- 为什么分库分表使用2的N次方 一个字节用两位16进制
你说说为神马表的总数.redis库的总数.HashMap的数量最好是2的N次方 数据在表库HashMap 落地时候都会跟总数取模,这个我们做个测试 假设数量是2的3次方就是8,即索引就是0-7 php ...
- 位运算 进制转化 STL中bitset用法
2017-08-17 16:27:29 writer:pprp /* 题目名称:输入十进制以二进制显示 程序说明:同上 作者:pprp 备注:无 日期:2017/8/17 */ #include &l ...
- md5加密--32位16进制小写
public class ttgameMd5 { public final static String MD5(String str) { char hexDigits[] = { // 用来将字节转 ...
随机推荐
- 负载均衡集群ipvsadm命令及基本用法
ipvsadm是LVS在应用层的管理命令,我们可以通过这个命令去管理LVS的配置.需要使用yum单独安装. 基本用法: ipvsadm COMMAND [protocol] service-addre ...
- Node单线程与异步编程的初步理解
最近学习了一些关于node的单线程与异步的知识,想拿过来和大家分享下: var async = require('async') //并行无关联,等待事件为最长时间请求过程.如以下两个任务执行时间 c ...
- MMU解读
转:https://blog.csdn.net/yueqian_scut/article/details/24816757 mmu页表也是放在内存中,mmu里有一个寄存器存放页表首地址,从而找到页表( ...
- Qt开发串口
首先,在工程文件里面, QT += serialport 在头文件里面, #include <QSerialPort> 1.配置打开串口 QSerialPort* myserial = n ...
- 字符串的hash匹配
如果要比较字符串是否相等,首先想到的是KMP算法,但是hash更加简洁易于编写,hash的目的是把一串字符转化成一个数字,用数字来比较是否相等.我让mod=912837417 Base=127,防止h ...
- 六款常见的Linux操作系统推荐
家常常可能因为工作或学习的需要,要使用个操作系统(比如Windows和Linux).大家对Windwos支持的文件系统可能比较熟悉,而对Linux操作系统所支持的文件系统也许比较陌生.下面小编为大家推 ...
- HP P420i Smart Array
http://blog.mpecsinc.ca/2013/02/hp-p420i-smart-array-adding-4-new-disks.html https://techzone.ergon. ...
- FckEditor 配置手册中文教程详细说明
http://www.jb51.net/article/17965.htm 首先,FCKEDITOR的性能是非常好的,用户只需很少的时间就可以载入 FCKEDITOR所需文件.对于其他在线编辑器来说, ...
- 真相大白:为什么Entity Framework不能进行跨数据库查询(附解决方法)
在上篇随笔中,我们发现Entity Framework在构建SQL语句时,将ToTable("CNBlogsTex.dbo.blog_PostBody")中的"CNBlo ...
- Netty原理
1. Netty简介Netty是一个高性能.异步事件驱动的NIO框架,基于JAVA NIO提供的API实现.它提供了对TCP.UDP和文件传输的支持,作为一个异步NIO框架,Netty的所有IO操作都 ...