本文参考了:
http://blog.csdn.net/canglingye/article/details/44177479
我刚一看,这不挺简单的吗?不断移位,看最低位是不是1,是1就记录一下,很简单嘛,而且移位又那么快。
class Solution:
def hammingWeight(self, n):
hw = 0
while n != 0:
if n & 1:
hw += 1
n >>= 1
return hw
然后提交就过了。上网一看。自己写的代码简直像是用脚写的……还if个毛啊。直接hw += (n & 1)就得了。
但这都不是重点。我又用JavaScript写了一次。跪了。(切不可乱装逼,但装逼的好处就是挫败以后能长知识)
var hammingWeight = function(n) {
var hw = 0;
while(n != 0){
if (n & 1) {
hw ++;
}
n >>= 1;
}
return hw;
};
错误:
Input: | 2147483648 (10000000000000000000000000000000) |
Output: | 0 |
Expected: | 1 |
Python因为不太在意变量类型,反正一大了就变长整型,所以没什么问题。C++、Java等应该也没问题,只要你指定参数是unsigned int。问题就出现在这个表面上不区分类型(一律都是var)实际会出问题的js。参考以下文章:
http://www.jb51.net/article/44242.htm
在 JavaScript 中,所有整数字变量默认都是有符号整数。JavaScript 进行位操作时,也是采用32位有符号整型,这意味着其转换的结果也是32位有符号整型。
有些时候,我们进行移位会出现意想不到的结果,以下是C语言 与 JS 的对比。
C语言
unsigned int a = 3774191835u;
unsigned int b = a >> 2;
/* b == 943547958 */
-------------------------------
JavaScript
var a = 3774191835;
var b = a >> 2;
/* b == -130193866 */
所以像我刚才那样的写法,移位最后会陷入死循环:10000000000000000000000000000000→11000000000000000000000000000000→11100000000000000000000000000000→……→11111111111111111111111111111111,到最后-1右移一位还是-1,死循环。
(如果把n!=0换成n>0也不行,负数直接退出循环。下文还会说。)
var hammingWeight = function(n) {
var hw = 0;
while(n){
n &= (n - 1);
hw ++;
}
return hw;
};
Input: | 4294967295 (11111111111111111111111111111111) |
Output: | 1 |
Expected: | 32 |