嵌入式C面试题-计算无符号整形变量中1的个数

来源:互联网 发布:手机淘宝怎么退货退款 编辑:程序博客网 时间:2024/05/01 18:38

考查位运行。这已经是一个非常常见的题目了,我这里主要也是收集了多种解法。自己拿定,面试官最想看到的吧。

(1)懂C的都能写出来的方式 ,这个时间复杂度花在循环上,由位数决定

int countBit(unsigned int n)

{

int count = 0;

while(n)

{

if(n&0x1)

count++;

n>>=1;

}

return count;

}


(2)更优秀一点的,我比较喜欢的。这个时间复杂度就有了优化,与n中一的位数有关。关键技巧点在n&=(n-1).  假如随便看几位n=000101,n-1=000100.  n&(n-1)=000100.所以可以看出,每次都是去掉了n中的低位的一个1.

int countBit(unsigned int n)

{

int count=0;

while(n)

{

n&=(n-1);

count++;

}

}


(3)有没有常数时间呢,当然是有的,最简单的就是想到用空间换时间。在《编程之美》里面有讲到这一方法,那是计算一个无符号8位的的值,建一个table[256],用n来做索引。这个方法 我不喜欢,想到这里,我们32位,就很难实现了,空间代价太大了。换另一种实现方式(4)吧


(4)这里就是数学的技巧和位运算的技巧了。

int countBit(unsigned int n)

{

int tmp = n;

        tmp = tmp - (tmp>>1) & 033333333333

                           - (tmp>>2) & 011111111111;

return ((tmp+tmp>>3) & 030707070707 )% 63;

}

我觉得第(2)(4)应该会给考官好的印像。


扩展 :给定两个正整数A和B,请问至少要改变多少位,才能使A变成B。

int tmp=A^B;

countBit(tmp);

就是想要的结果。该拓展也是来自《编程之美》的问题。

0 0
原创粉丝点击