2.66 表示在x二进制表示中最左端1的掩码

来源:互联网 发布:gta5驾驶优化mod 编辑:程序博客网 时间:2024/04/30 13:53

题目:Generate mask indicating leftmost 1 in x.Assume w=32.

For example 0xFF00 -> 0x8000,and 0x6600 --> 0x4000

要求,代码中最多只能包含15个算术运算符、位运算和逻辑运算

方法一:

int leftmost_one(unsigned  x){int result=x;if(0!=x){while(x){result=x;x=x&(x-1);}}return result;}

这段代码的估计是比较常见的解题思路了,时间复杂度O(n),空间复杂度O(1),显然不符合要求,虽然一次循环只有1次位运算加一次算术运算,但是如果32位全为1,则需要32*2个运算符。

方法二:

int leftmost_one1(unsigned  x){if(x>(1<<31)){x=0x80000000;}if(0!=x&&x<(1<<31)){x=x|(x>>1);x=x|(x>>2);x=x|(x>>4);x=x|(x>>8);x=x|(x>>16);x+=1;x=x>>1;}return x;}
本来我习惯于程序只有一个入口一个出口,就像上面这样,但是为了满足对15的限制只好改成下面这样了:

int leftmost_one1(unsigned  x){if(x==0){return x;}if(x>(1<<31)){return 0x80000000;}x=x|(x>>1);x=x|(x>>2);x=x|(x>>4);x=x|(x>>8);x=x|(x>>16);x+=1;x=x>>1;return x;}

这段代码是我想了好久才搞定,时间复杂度O(1),空间复杂度O(1).个人感觉还算比较优雅,基本原理是这样的:

假设x是8位表示的(0100 1010),最终上面的代码的前5次结果为0111 1111,最后加1再往右移一个单位就得到需要的掩码了。其实这道题的思路是跟上一道题的原理差不多,不懂的网友可以参考上一篇的分析。

原创粉丝点击