题目地址:二进制中1的个数
题目描述
输入一个整数,输出该数32位二进制表示中1的个数。其中负数用补码表示。
题目示例
输入:
10
返回值:
2
解法分析
解这道题需要了解源码、反码和补码的相关知识。
首先我们可以从右移操作入手,一个整数若右移1,如果最右位是0,那么相当于该整数除以2,如果最右位是1,那么相当于先减1再除以2(其实就是看除以2之后是奇数还是偶数),因此我们可以由此得到算法1;
但我们会发现,这样会需要我们循环32次(因为该数表示为32位二进制),有没有更快的算法呢?
当我们用一个整数,去和比其小1的整数做与运算时,该整数最右位的1会变成0。比如6(1010)和5(1001)做与运算,结果是1000,可以发现1010最右侧的1变成了0。我们可以使用这个方法来计算n包含几个1,且运算次数与n中1的个数相同。此方法对以补码表示的负数同样适用。见算法2。
代码
算法1:
1 function NumberOf1(n) 2 { 3 // write code here 4 var num = 0; 5 var m,k; 6 for(var i=0;i<32;i++){ 7 m = n/2; 8 k = n >> 1; 9 if(m != k){ 10 num++; 11 } 12 n = Math.floor(m); 13 } 14 return num; 15 }
算法2:
1 unction NumberOf1(n) 2 { 3 // write code here 4 var num = 0; 5 while (n){ 6 n = n & (n-1); 7 num++; 8 } 9 return num; 10 }
执行结果