求下面函数的返回值(微软),假定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).执行时间也是确定的。空间换时间在某些情况下是个好的选择,比如需要频繁使用这个算法的时候,但也不是尽然,还是得视情况而定。

面试题--位操作---延伸到一个用空间换取时间效率的例子相关推荐

  1. Hadoop推测执行(以空间换取时间)

    1. 背景 Speculative Task,又叫推测式任务,是指在分布式集群环境下,因为程序bug,负载不均衡或者资源分布不均,造成同一个job的多个task运行速度不一致,有的task运行速度明显 ...

  2. 空间换时间,查表法的经典例子

    前言 上一篇分享了:C语言精华知识:表驱动法编程实践 这一篇再分享一个查表法经典的例子. 我们怎么衡量一个函数/代码块/算法的优劣呢?这需要从多个角度看待.本篇笔记我们先不考虑代码可读性.规范性.可移 ...

  3. 以空间换时间——动态规划算法及其应用:矩阵链相乘

    动态规划算法是5大算法基础中最重要的一个,它专门用来解决平面世界下的应用,即会多次使用二维数组. 当然动态规划算法是空间换时间的算法,也就是说:我们可以利用空间资源来使某算法问题的时间复杂度降到最低. ...

  4. 数据表从一个表空间中移动到另一个表空间中

    数据表从一个表空间中移动到另一个表空间中 1) alter table [table_name] move tablespace [new tablespace]; 移动LOB字段 2) alter ...

  5. 【IT笔试面试题整理】判断一个树是否是另一个的子树

    [试题描述]定义一个函数,输入判断一个树是否是另一个对的子树 You have two very large binary trees: T1, with millions of nodes, and ...

  6. 将编号为0和1的两个栈存放于一个数组空间V[m]中。

    目录 1.题目描述 2.算法实现 1.题目描述 将编号为0和1的两个栈存放于一个数组空间V[m]中,栈底分别处于数组的两端.当第0号栈的栈顶指针top[0]等于-1时该栈为空:当第1号栈的栈顶指针to ...

  7. oracle查看所有用户_Oracle实用命令查看共用一个表空间的所有用户

    概述 有朋友问到如何查出表空间都被哪些用户使用的一些方法,因为有几种情况需要考虑,也顺便做个总结. 需求:如何查看共用一个表空间的所有用户 查看某表空间下表的所有者 使用dba用户查询: 1.如果先要 ...

  8. ftp linux 推送文件_Linux下SSH用FTP命令上传文件至另一个FTP空间

    如果没有ftp 提示: -bash: ftp: command not found 请先安装ftp应用程序: yum install ftp #ftp 127.0.0.1 21 输入远程空间的FTP ...

  9. 创建一个动态空间存储未知大小的二维数组

    创建一个动态空间存储未知大小的二维数组 在c/c++中,数组往往只能在给定大小的时候才能使用,否则就需要创建一个足够大的数组进行存储,这样造成空间资源的浪费. 但在很多情况下,我们往往需要一个变量来确 ...

最新文章

  1. 我写了一个面向源码阅读者的 UI 框架(基于 Vue)
  2. Flex Socket 与 C# 通信
  3. Asp.net实现在线截图(大图截取为小图)
  4. 神经网络与机器学习 笔记—核方法和径向基函数网络(上)
  5. 学习CSS 不错网址
  6. 时间串变成Date类型的数据
  7. PC介绍之PCIE、总线、内存、电源
  8. onethink后台登陆修改验证码!
  9. 迅雷BT下载电影99.9%不动原地循环解决方案
  10. Google Pixel 2拍照黑科技:单摄搞定背景虚化+内部潜伏神秘芯片
  11. tcp序列号为什么是随机的_TCP与UDP
  12. 2010-2020年全国poi兴趣点
  13. 2022年最新过DD检测方法dd防检测方法
  14. OneNote 安装代码高亮插件 NoteHightlight的安装及使用基础教程
  15. 数据结构期末考试试题及答案
  16. GhostScript 沙箱绕过(命令执行)漏洞(CVE-2018-19475)复现
  17. 心理学与生活 - 发展与教育
  18. 台式计算机如何组装,怎样组装基本台式机
  19. 计算机专业认识和规划,计算机科学与技术专业认识与规划
  20. 新能源车牌识别技术发展到哪一步了?

热门文章

  1. wps(已保存至云文档)如何找到云文档
  2. dnf一换线就服务器不稳定,DNF:史派克做事了!换线黑屏已解决,玩家点取消可返回其它频道...
  3. Ceph数据恢复初探
  4. 基于 Ruby 谈谈——程序设计语言的通用框架
  5. 微信打开网址添加在浏览器中打开提示 http://caibaojian.com/weixin-tip.html
  6. 靳东正式起诉抖音:案由涉及网络侵权责任纠纷
  7. 网络购物纠纷起诉用什么证明材料
  8. 基于UWB和IMU融合的MAV群精确三维定位
  9. 台式计算机电池能充电吗,电脑的充电线可以一直充电吗?对电脑电池是否有损害?...
  10. 智能机器人与智能系统(大连理工大学庄严教授)——4.自主机器人