数据结构与算法(位运算) --javascript语言描述

二进制中1的个数

请实现一个函数,输入一个整数,输出该数二进制表示1的个数。例如把9表示成二进制是1001,有2位是1。所以若是输入9,该函数输出2。算法

首先对于二进制1的求解,在这里,咱们最应该想到的就是关于位运算的一些操做符。总共有五种运算,分别是:与(&),或(|),异或(^),右移(>>),左移(<<)。函数

第一种可能会引发死循环的解法:
思路1:先对你所给的这个整数进行判断,这个数的最右边是否是1。若是是1,给一个计数器,给它加1。接着把输入的整数右移一位,这样一直进行移位,最后直到这个整数变成0为止,而后输出计数器就行了。code

function NumberOf1(n)
{
  let count = 0;
  while(n) {
    if(n & 1) {
      count ++;
    }
    n = n >> 1;
  }
  return count;
}
console.log(NumberOf1(9));

这个算法对于无符号数来讲没有问题,但是对于有符号数问题就大了,极有可能形成死循环。当n为负数时,n右移在最高位补1(为了保证数据为负数),于是最终就会造成死循环。好比:0x80000000时,这时候就会出现问题,当右移一位的时候时,就变成了0xC0000000。由于是对负数的移位,因此必须保证移位后是个负数,因此最高位永远都会是1,因此也就意味这最终这个数字永远会死循环下去。io

思路2:移动1,先判断最低位是否是1,而后把1移成2。再与整数比比较,就能判断倒数第二位是否是1,依次下去。。。这样最终就能达成一个效果,获得全部的1的个数。console

function NumberOf1(n) {

  let count = 0;
  let flag = 1;
  while(flag) {
    if(n & flag) {
      count ++;
    }
    flag = flag << 1;
  }
  return count;
}
console.log(NumberOf1(9));

最后,咱们提供出来一种最好的方法。function

思路3:把一个整数减去了1,再和原整数作与运算,会把这个整数最右边一个1变成0,而且把这个1后面的0都变成1。那么一个整数的二进制有多少个1,就能够进行多少次这样的操做,最后,经过把计数器肯定运算次数,输出计数器就行了。循环

//更好的解法
function NumberOf1(n) {
  let count = 0;
  while(n) {
    count ++;
    n = (n-1) & n;
  }
  return count;
}
console.log(NumberOf1(9));
相关文章
相关标签/搜索