zoukankan      html  css  js  c++  java
  • 剑指offer 二进制中1的个数

    题目描述

    输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
     
    代码一:
     1 class Solution {
     2 public:
     3      int  NumberOf1(int n) {
     4          int count = 0;
     5          while (n) {
     6              if (n & 1) {
     7                  count++;
     8              }
     9              n >>= 1;
    10              //n = n & (n - 1);
    11              
    12          }
    13          return count;
    14      }
    15 };

    有问题,出现死循环,原因在于如果输入的是负数, 如0x80000000, 右移一位之后会变成0xC0000000, 而不是0x40000000,经过多次移位,最终会变成0xFFFFFFFF

    代码二:我们不右移数字,而是左移1.这种做法,32位的整数需要左移32次

     1 class Solution {
     2 public:
     3      int  NumberOf1(int n) {
     4          int count = 0;
     5          unsigned int flag = 1;
     6          while (flag) {
     7              if (n & flag) {
     8                  count++;
     9              }
    10              flag <<= 1;
    11              //n = n & (n - 1);
    12              
    13          }
    14          return count;
    15      }
    16 };

    代码三:每一次 n & (n - 1)操作相当于把n对应二进制最右边的1变成0,循环次数为n中1的个数。

    class Solution {
    public:
         int  NumberOf1(int n) {
             int count = 0;
             while (n) {
                 count++;
                 n &= n - 1;
                 
             }
             return count;
         }
    };

    相关题目:

    1、输入两个整数m和n, 计算需要改变m的二进制表示中的多少位才能得到n。

    思路:第一步:将两个数进行异或操作(^),得到两个数的二进制差别,

    第二步:统计异或结果中1的个数。

    2、用一条语句判断一个整数是否是2的整数次方。

    思路:如果一个数是2的整数次方,那么它的二进制表示中有且只有一位是1, 那么n & (n - 1) = 0。

  • 相关阅读:
    luogu_P1850 换教室
    luogu_P3224 [HNOI2012]永无乡
    luogu_P1064 金明的预算方案
    luogu_P2014 选课
    luogu_P3372 【模板】线段树 1(动态开点)
    luogu_P2852 [USACO06DEC]牛奶模式Milk Patterns
    luogu_P1941 飞扬的小鸟
    luogu_P2678 跳石头
    luogu_P1638 逛画展
    【Tyvj2046】掷骰子
  • 原文地址:https://www.cnblogs.com/qinduanyinghua/p/11246110.html
Copyright © 2011-2022 走看看