面试题--位操作---延伸到一个用空间换取时间效率的例子
求下面函数的返回值(微软),假定x = 9999.
int func(x)
{
int countx = 0;
while(x)
{
countx ++;
x = x&(x-1);
}
return countx;
}
这题咋一看,不知道countx在数什么,仔细一想,x和x-1进行位操作结果怎样呢,用二进制表示去展开,很显然的明白是将最右边的(不一定是末位)1变成0,countx++,然后X会变成2的N次幂,直到x的最左边的1变为0,所以countx数的是十进制x的二进制表示中含1的个数。那么9999的二进制表示时多少呢?能迅速写出来吗?不能,只能按步就班的算,(要淡定,这也是一个考点吧,看懂了题目还要有耐心去算)2的10次方1024,13次8192,差不多了,9次方512,8次方256,8192+1024+512+256=9984,差15即1111故结果为8.
由这道题,可以知道
x&(x-1)
可以计算x的二进制中包含的1的个数。如果要计算0的个数呢?。。。。可以先与0XFFFFFFFF进行与或后,就变成求1的个数了,也就是原来0的个数。当然可以32-1的个数就是0的个数。
还可以判断一个数是不是2的N次幂,x&(x-1)==0 则x是2的幂方。
延伸----一个用空间换取时间的例子.
题目描述:对于一个字节(8bit)的无符号整形变量,求二进制表示中“1”的个数,要求算法执行效率尽可能地高。
很显然的想到用位操作x&(x-1)来计算。如果没有想到这个很自然的会想到用逐次移位,然后与1比较,程序如下:
unsigned char Count(unsigned char byt)
{
unsigned char num=0;
while (byt)
{
num += (byt & 0×01);
byt >>= 1;
}
return num;
}
这个方法,不如x&(x-1)效率高。因为不管有多少个1都要循环8次,执行效率不高,但是执行该函数的时间每次都是确定的。
int Count(BYTE v)
{
int num=0;
while (v)
{
v &=(v-1); //v=v&(v-1)这个操作可以直接消除掉v中的最右边的1。
num++;
}
return num;
}
循环的次数是BYTE中1的个数,无需遍历。循环次数与Byte中1的个数有关,但是函数执行时间不确定,不过效率比前面的要提高了很多,是不是以为这就是最佳答案了吧,告诉你:NO。
方法三、
查表法,这个的效率应该是最高的了——空间换时间。将0~255各个数中所含的1列出来,查表!!
int countTable[256]=
{
0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,
1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8
};
int Count(BYTE v)
{
return countTable[v];
}
这个程序要求效率尽可能的高,显然最后一种的时间复杂度最低了O(1).执行时间也是确定的。空间换时间在某些情况下是个好的选择,比如需要频繁使用这个算法的时候,但也不是尽然,还是得视情况而定。
面试题--位操作---延伸到一个用空间换取时间效率的例子相关推荐
- Hadoop推测执行(以空间换取时间)
1. 背景 Speculative Task,又叫推测式任务,是指在分布式集群环境下,因为程序bug,负载不均衡或者资源分布不均,造成同一个job的多个task运行速度不一致,有的task运行速度明显 ...
- 空间换时间,查表法的经典例子
前言 上一篇分享了:C语言精华知识:表驱动法编程实践 这一篇再分享一个查表法经典的例子. 我们怎么衡量一个函数/代码块/算法的优劣呢?这需要从多个角度看待.本篇笔记我们先不考虑代码可读性.规范性.可移 ...
- 以空间换时间——动态规划算法及其应用:矩阵链相乘
动态规划算法是5大算法基础中最重要的一个,它专门用来解决平面世界下的应用,即会多次使用二维数组. 当然动态规划算法是空间换时间的算法,也就是说:我们可以利用空间资源来使某算法问题的时间复杂度降到最低. ...
- 数据表从一个表空间中移动到另一个表空间中
数据表从一个表空间中移动到另一个表空间中 1) alter table [table_name] move tablespace [new tablespace]; 移动LOB字段 2) alter ...
- 【IT笔试面试题整理】判断一个树是否是另一个的子树
[试题描述]定义一个函数,输入判断一个树是否是另一个对的子树 You have two very large binary trees: T1, with millions of nodes, and ...
- 将编号为0和1的两个栈存放于一个数组空间V[m]中。
目录 1.题目描述 2.算法实现 1.题目描述 将编号为0和1的两个栈存放于一个数组空间V[m]中,栈底分别处于数组的两端.当第0号栈的栈顶指针top[0]等于-1时该栈为空:当第1号栈的栈顶指针to ...
- oracle查看所有用户_Oracle实用命令查看共用一个表空间的所有用户
概述 有朋友问到如何查出表空间都被哪些用户使用的一些方法,因为有几种情况需要考虑,也顺便做个总结. 需求:如何查看共用一个表空间的所有用户 查看某表空间下表的所有者 使用dba用户查询: 1.如果先要 ...
- ftp linux 推送文件_Linux下SSH用FTP命令上传文件至另一个FTP空间
如果没有ftp 提示: -bash: ftp: command not found 请先安装ftp应用程序: yum install ftp #ftp 127.0.0.1 21 输入远程空间的FTP ...
- 创建一个动态空间存储未知大小的二维数组
创建一个动态空间存储未知大小的二维数组 在c/c++中,数组往往只能在给定大小的时候才能使用,否则就需要创建一个足够大的数组进行存储,这样造成空间资源的浪费. 但在很多情况下,我们往往需要一个变量来确 ...
最新文章
- 我写了一个面向源码阅读者的 UI 框架(基于 Vue)
- Flex Socket 与 C# 通信
- Asp.net实现在线截图(大图截取为小图)
- 神经网络与机器学习 笔记—核方法和径向基函数网络(上)
- 学习CSS 不错网址
- 时间串变成Date类型的数据
- PC介绍之PCIE、总线、内存、电源
- onethink后台登陆修改验证码!
- 迅雷BT下载电影99.9%不动原地循环解决方案
- Google Pixel 2拍照黑科技:单摄搞定背景虚化+内部潜伏神秘芯片
- tcp序列号为什么是随机的_TCP与UDP
- 2010-2020年全国poi兴趣点
- 2022年最新过DD检测方法dd防检测方法
- OneNote 安装代码高亮插件 NoteHightlight的安装及使用基础教程
- 数据结构期末考试试题及答案
- GhostScript 沙箱绕过(命令执行)漏洞(CVE-2018-19475)复现
- 心理学与生活 - 发展与教育
- 台式计算机如何组装,怎样组装基本台式机
- 计算机专业认识和规划,计算机科学与技术专业认识与规划
- 新能源车牌识别技术发展到哪一步了?
热门文章
- wps(已保存至云文档)如何找到云文档
- dnf一换线就服务器不稳定,DNF:史派克做事了!换线黑屏已解决,玩家点取消可返回其它频道...
- Ceph数据恢复初探
- 基于 Ruby 谈谈——程序设计语言的通用框架
- 微信打开网址添加在浏览器中打开提示 http://caibaojian.com/weixin-tip.html
- 靳东正式起诉抖音:案由涉及网络侵权责任纠纷
- 网络购物纠纷起诉用什么证明材料
- 基于UWB和IMU融合的MAV群精确三维定位
- 台式计算机电池能充电吗,电脑的充电线可以一直充电吗?对电脑电池是否有损害?...
- 智能机器人与智能系统(大连理工大学庄严教授)——4.自主机器人