[剑指Offer]-二进制中1的个数

博客围绕计算整数二进制中1的个数展开。先补充位运算知识,包括与、或、异或及左右移运算规则。接着给出题目,要求实现函数计算输入整数二进制中1的个数。然后介绍三种解题思路,分析了可能出现的问题及效率情况,最后提及源码在Github上。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

补充知识:位运算

  • 基础与、或、异或运算
与(&)或(|)异或(^)
0&0=00|0=00^0=0
0&1=01|0=11^0=1
1&0=00|1=10^1=1
1&1=11|1=11^1=0
有0则0有1则1同出0不同出1
  • 左移

左移n位最左边的n为直接丢弃,右边补n个0.

00001010<<2=00101000

  • 右移

正数:直接右边n个0抛弃,左边补0;
负数:直接右边n个0抛弃,左边补上n个1;

00001010>>2=00000010
10001010>>3=11110001

题目描述

请实现一个函数,输入一个整数,输出该数二进制表示中1的个数。例如把9表示成二进制是1001,有2位是1 因此如果输入9,该函数输出2;

解题思路
  • 将正数和1做与运算,如果为1则记录加1(循环一次整数右移一次)。可能引起死循环。
  • 将1来左移,如果与运算为1就记录加1,直到结果为0.。对于int这样的数据类型(32位 左移32次 因为int占4字节 也就是32位),移动次数太多,效率低。
  • 将整数-1,再与原数据做与运算,运算一次消耗掉原数据一个1,直到为0截止。只需要循环n个1次。
算法图解

第二:
在这里插入图片描述
第三:
在这里插入图片描述

参考代码:
package offer;

/**
 * 请实现一个函数,输入一个整数,输出该数二进制表示中1的个数。例如把9表示成二进制是1001,有2位是1 因此如果输入9,该函数输出2;
 */
public class Offer15 {
    public static void main(String[] args) {
        int nums = 9;
      System.out.println(NumBerOf1(nums));
        //  System.out.println(HNumBerOf1(nums));
    }
    // 可能引起死循环的解法1
    public static int numberof1_1(int n) {
        int count = 0;
        while (n != 0) {
            if ((n & 1) != 0) {
                count++;
            }
            n = n >> 1;
        }
        return count;
    }
    /**
     * 常规写法  将1 来左移 与原数据按位做与运算
     * 32位 左移32次  因为int占4字节  也就是32位
     *
     * @param n
     * @return
     */
    static int NumBerOf1(int n) {
        int count = 0;
        int flag = 1;
        while (flag != 0) {
            System.out.println((n & flag));
            if ((n & flag) != 0) {

                count++;
            }
            flag = flag << 1;
        }

        return count;
    }

    /**
     * 减1后与运算 直到等于0
     * @param n
     * @return
     */
    static int HNumBerOf1(int n) {
        int count = 0;
        while (n != 0) {
           ++count;
           n=(n-1)&n;
        }

        return count;
    }
   
}


附录

该题源码在我的 ?Github 上面!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值