不得不说位操作确实是一个十分不错的操作,只是简单的几步就足以笑傲江湖,今天看两道简单位操作面试题
二进制中1的个数:实现一个函数,输入一个整数,输出该整数二进制中1的个数
分析:这还不简单,直接让这个整数依次往右边移动一位,与1做与运算&,然后统计1的个数,等等,有诈,万一是负数的话,这不就成死循环了吗,思考片刻,简单,这次就让1不断的往左边移动,然后去与整数做与运算&,这也是可以的。。。再等等,万一这台机器是坑爹的128位,就算是32位那效率也是不高的啊,思考良久,终于有了一个稳妥的办法
稳妥办法: 举个例子,假设一个整数的二进制序列是1100,那么将二进制序列-1会得到1011,此时再将1100&1011=1000,哈哈,想到了吧只要将整数&(整数-1)就会得到剩下的1,此等解法只需要比较整数中1的个数次即可。
部分代码(C/C++)
int Num(int n){
int count=0;
while(n){
count++;
n=(n-1)&n;
}
return count;
}
嗯,效果不错,算是一个比较好的解法了。
三种错误的处理方式:API、全局变量、异常,需要考虑的是功能测试、边界测试、负面测试
数值的整数次方:实现一个pow()函数,不用考虑大数问题
分析:这还不简单,直接用一个for循环就可以解决战斗,但有诈,万一这个出现负数和0的情况那不就GG了,所以得考虑边界测试和负面测试,但还是可以接受的,加入0和负数的判断即可,但要注意double类型比较“==”时不准确,一般想到这就差不多了,但是凡是都有例外,这里有个更好的解法。
稳妥办法: 由公式 an=an/2∙an/2(n为偶数),an=an−1∙an−1∙a(n为奇数)
这个公式实在是太棒了,虽然很简单,但是却十分的奏效,利用它结合神奇的递归,就可以以简单的代码实现上面的题目了。
完整代码(C/C++)
#include<stdio.h>
double power(double base,unsigned int e){
if(e==0)
return 1;
if(e==1)
return base;
double result=power(base,e>>1);
result*=result;
if(e&1==1)
result*=base;
return result;
}
int main(){
double base;
scanf("%lf",&base);
unsigned int e;
scanf("%d",&e);
if(base-0<0.0001){
printf("input error");
return 0;
}
double s=power(base,e);
printf("the pow(%lf,%d)=%lf",base,e,s);
return 0;
}
小结
今天上线的两道位操作题目比较简单,重点是梳理位操作在实战中的应用,因为在讲究效率的当代,一个好的操作是会起到很棒的效果的,不得不说,剑指offer确实是一本好书,接下来继续辛勤工作。。