剑指offer 面试题 (二进制中 1 的个数)(4)
来源:互联网 发布:c语言或符号 编辑:程序博客网 时间:2024/05/01 06:15
# 面试题: 求一个整数二进制中 1 的个数?
/*
题目: 请实现一个函数,输入一个整数,输出该数二进制表示中 1 的个数。
例如把 9 表示为二进制是 1001, 有两个 1;因此,如果输入 9,则输出 2;
*/
题目分析:
学过计算机机基础的同学应该都知道,在计算机中的存储都是以二进制形式存在的! 那么求出一个整数
二进制中 1 的个数,当然不在话下了, 看到这道题的的时候应该都是信息满满; 注意: 当面试的时候遇到这道题,
就得仔细思考一下了,面试官不会那么无聊吧! 无非就是把整数变成二进制,用计数器加出来其中 1 的个数嘛1 !
对,没问题,那么问题就在于实现时的细节了,老话常说:细节决定成败!
算法选择:
已经很明确了,选择计数器,循环; 那么我们来看下面实现的几个版本有什么不同!
代码实现: @算法 (一)>>>>将num 的二进制和1进行按位&, 则&操作两个都为 1 结果才为1 ,否则为 0;
用每次结果为1时 ,count+1;
int NumberOf1(num){int count = 0;//计数器while(num){/* 这块的num&1 相当于 num%2;num>>1相当于num / 2; 但是移位运算要比除法运算的效率高得多! */if(num & 1)count++;num = num>>1;}return count;}
代码反思: 代码写到这,并不代表就完事了,还要测试一下啊,多测试几组数据你就会发现,输入 -1,的时候会死循
环,这是因为负数的符号位是 1 (这个在计算机基础里面有); 并不是你把最高位的 1 右移之后就变成 0 了;例
如: 10000000 00000000 0000000 00000001 这是(-1)
11000000 00000000 0000000 00000000 (-1)右移一位之后最高位的 1 不变;
所以程序会死循环;那么就有了下面的改进:
代码实现: @算法(二) 设置一个标志位,移动标志位不移动 num 本身;即 另flag=1,然后num 和 flag按位&
如果&的结果是1 .则count++; 每次&完,flag左移一位;就解决了负数问题;例如:进行一次循环
num = -1: 10000000 00000000 0000000 00000001 ;
flag = 1 : 00000000 00000000 0000000 00000001 ;
num&flag: 00000000 00000000 0000000 00000001 ;
flag<<=1: 00000000 00000000 0000000 00000010 ;
然后进行下次循环flag和num 的第31位进行比较,一次类推循环32次!
int NumberOf1(num){int count = 0;//计数器int flag = 1;while(flag)//循环32次后flag自动变为0;{if(num & flag)count++;flag = flag << 1;}return count;}
@与此类似的for循环32次的代码如下:
int NumberOf1(num){int count = 0;//计数器int i =0;for(;i<32;i++){if(num & 1)count++;num>>=1;}return count;}
ps: 写到这里,是不是觉得应该完了吧! 就这么一个题! but,答案是否定的, 假面试官告诉你,觉得还有有些麻
烦,让你改一下,num中有几个 1 就循环几次;
你该怎么做?
/*
这下就得好好开动脑子了,这才有些算法的味道出来了;
那么我们就开始分析吧! 首先,先例一个数出来吧,比如 7;二进制为: .....0111; 前面的0省略了,反正人家就要
求有几个1循环几次(别忘了负数)减去一个 1试试,变成: .....0110; 再将num-1 和 num 按位&一下是不是把右
边的一个1变为了 0; 那么规律来了,只要num不为0,那么它总有一位是1;那就count++;接着将 num & num-1; 因
为你已经count++了,所以就应该让num少一个 1 ; 循环起来;
*/
代码实现: @算法(三) 有几个1 循环几次;
int NumberOf1(num){int count = 0;//计数器while(num){++count;num = num & (num - 1);}return count;}
over !
thanks!
1 0
- 剑指offer 面试题 (二进制中 1 的个数)(4)
- [剑指offer][面试题10]二进制中1的个数
- 《剑指offer》面试题10二进制中1的个数
- 【剑指offer】面试题10:二进制中1的个数
- 【剑指offer】面试题10:二进制中1的个数
- 剑指offer 面试题10 二进制中1的个数
- 剑指Offer:面试题10 二进制中1的个数
- 《剑指Offer》面试题10:二进制中1的个数
- 剑指offer-面试题10-二进制中1的个数
- 【剑指offer】 面试题10: 二进制中1的个数
- 剑指offer-面试题10:二进制中1的个数
- 剑指offer面试题 二进制中1的个数
- 剑指Offer----面试题10:二进制中1的个数
- 【剑指offer】面试题10: 二进制中1的个数
- 剑指offer面试题10:二进制中1的个数
- 剑指offer--面试题10:二进制中1的个数
- 剑指offer-面试题10-二进制中1的个数
- 【剑指offer】面试题10:二进制中1的个数
- 基于建立模板的消除水下扭曲成像
- java类
- bestcoder 放盘子
- MapGIS6.7_学习中遇到的问题(4):用户点文件(.txt)转MapGIS点文件(.WT)
- 数组做数组成员 2
- 剑指offer 面试题 (二进制中 1 的个数)(4)
- 解密所有APP运行过程中的内部逻辑
- IO
- Linux 目录说明
- Jenkins -- 插件开发之一环境搭建
- 临时数据转化为mysql表与现有表进行join
- hive设置reduce的最大值
- DateTimePicker:jQuery日期和时间插件
- 快速排序及其改进算法C++实现