本文参考自《剑指offer》一书,代码采用Java语言。

更多:《剑指Offer》Java实现合集  

题目

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

思路

  遇到与二进制有关的题目,应该想到位运算(与、或、异或、左移、右移)。

  方法一:”与运算“有一个性质:通过与对应位上为1,其余位为0的数进行与运算,可以某一整数指定位上的值。这道题中,先把整数n与1做与运算,判断最低位是否为1;接着把1左移一位,与n做与运算,可以判断次低位是否为1……反复左移,即可对每一个位置都进行判断,从而可以获得1的个数。这种方法需要循环判断32次。

  方法二(better):如果一个整数不为0,把这个整数减1,那么原来处在整数最右边的1就会变为0,原来在1后面的所有的0都会变成1。其余所有位将不会受到影响。再把原来的整数和减去1之后的结果做与运算,从原来整数最右边一个1那一位开始所有位都会变成0。因此,把一个整数减1,再和原来的整数做与运算,会把该整数最右边的1变成0。这种方法,整数中有几个1,就只需要循环判断几次。

测试用例

  1.正数(包括边界值1、0x7FFFFFFF)

  2.负数(包括边界值0x80000000、0xFFFFFFFF)

  3.0

完整Java代码

(含测试代码)

/**
*
* @Description 面试题15:二进制中1的个数
*
* @author yongh
* @date 2018年9月17日 下午3:01:16
*/ // 题目:请实现一个函数,输入一个整数,输出该数二进制表示中1的个数。例如
// 把9表示成二进制是1001,有2位是1。因此如果输入9,该函数输出2。 public class NumberOf1InBinary {
public int NumberOf1_Solution1(int n) {
int count = 0;
int flag = 1;
while (flag != 0) {
if ((flag & n) != 0)
count++;
flag = flag << 1;
}
return count;
} public int NumberOf1_Solution2(int n) {
int count = 0;
while (n != 0) {
count++;
n = (n - 1) & n;
}
return count;
} // =========测试代码========= void test(String testName, int n, int expected) {
if (testName != null)
System.out.println(testName + ":");
if (NumberOf1_Solution1(n) == expected) {
System.out.print(" soluton1:" + "passed ");
} else {
System.out.print(" solution1:" + "failed ");
} if (NumberOf1_Solution2(n) == expected) {
System.out.println("soluton2:" + "passed ");
} else {
System.out.println("solution2:" + "failed ");
}
} void test1() {
test("Test for 0", 0, 0);
} void test2() {
test("Test for 1", 1, 1);
} void test3() {
test("Test for 10", 10, 2);
} void test4() {
test("Test for 0x7FFFFFFF", 0x7FFFFFFF, 31);
} void test5() {
test("Test for 0xFFFFFFFF", 0xFFFFFFFF, 32);
} void test6() {
test("Test for 0x80000000", 0x80000000, 1);
} public static void main(String[] args) {
NumberOf1InBinary demo = new NumberOf1InBinary();
demo.test1();
demo.test2();
demo.test3();
demo.test4();
demo.test5();
demo.test6();
}
}

    

Test for :
soluton1:passed soluton2:passed
Test for :
soluton1:passed soluton2:passed
Test for :
soluton1:passed soluton2:passed
Test for 0x7FFFFFFF:
soluton1:passed soluton2:passed
Test for 0xFFFFFFFF:
soluton1:passed soluton2:passed
Test for 0x80000000:
soluton1:passed soluton2:passed

NumberOf1InBinary

收获

  1.与二进制有关的题目要往位运算方面想,复习一下:二进制位运算的几个用法

  2.注意:负数右移还是负数!即如果对n=0x8000 0000右移,最高位的1是不会变的。如果这道题目通过令n=n>>1来计算n中1的个数,该数最终会变成0xFFFF FFFF而陷入死循环!

  3.把一个整数减1,再和原来的整数做与运算,会把该整数最右边的1变成0。这种方法一定要牢牢记住,很多情况下都可能用到,例如:

   1)一句话判断一个整数是否为2的整数次方;

   2)对两个整数m和n,计算需要改变m二进制表示中的几位才能得到n。

  4.与数字操作有关的题目,测试时注意边界值的问题。对于32位数字,其正数的边界值为1、0x7FFFFFFF,负数的边界值为0x80000000、0xFFFFFFFF。

  5.几个细节问题

   1)flag=flag<<1,而不是只写一句flag<<1;

   2)flag&n!=0,而非flag&n==1; 也就不能写成count+=(flag&1)了

   3)if语句中,不能写为if(flag&n!=0) ,而要写成 if((flag&n)!=0),需要注意一下

更多:《剑指Offer》Java实现合集  

【Java】 剑指offer(14) 二进制中1的个数的更多相关文章

  1. 《剑指offer》 二进制中1的个数

    本题来自<剑指offer> 二进制中1的个数 题目: 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 思路: 两种思路: 第一种:对n进行左移,检测最后一位是否为1,但考 ...

  2. 剑指 Offer 15. 二进制中1的个数

    剑指 Offer 15. 二进制中1的个数 Offer 15 题目描述: 方法一:使用1逐位相与的方式来判断每位是否为1 /** * 方法一:使用1逐位与的方法 */ public class Off ...

  3. 刷题-力扣-剑指 Offer 15. 二进制中1的个数

    剑指 Offer 15. 二进制中1的个数 题目链接 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/er-jin-zhi-zhong-1de- ...

  4. 剑指Offer:二进制中1的个数

    题目:输入一个整数,输出该数二进制表示中1的个数. // 二进制中1的个数 #include <stdio.h> int wrong_count_1_bits(int n) // 错误解法 ...

  5. Go语言实现:【剑指offer】二进制中1的个数

    该题目来源于牛客网<剑指offer>专题. 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 分析: 如果一个整数不为0,那么这个整数至少有一位是1.如果我们把这个整数减1 ...

  6. 剑指offer例题——二进制中1的个数

    题目:输入一个整数,输出该二进制表示中1的个数.其中负数用补码表示. 首先明确补码的定义: 原码 反码 补码 将最高位作为符号位(0表示正,1表示负), 其它数字位表达数值本身的绝对值的数字表示方式 ...

  7. 剑指offer 11二进制中1的个数

    输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. java版本: public class Solution { public int NumberOf1(int n) { Strin ...

  8. 《剑指offer》二进制中1的个数

    一.题目描述 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 二.牛客网提供的框架 class Solution { public: int NumberOf1(int n) { } ...

  9. 剑指Offer之二进制中1的个数

    题目描述 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示.     解法1:使用Integer.toBinanryString()返回int变量的二进制表示的字符串. [在Intege ...

随机推荐

  1. ping不同网站总结

    用高级设置法预防Ping 用网络防火墙阻隔Ping 启用IP安全策略防Ping IP安全机制(IP Security)即IPSec策略,用来配置IPSec安全服务.这些策略可为多数现有网络中地多数通信 ...

  2. Java SE之基本程序设计结构

     概述:    0.注释    1.基本数据类型(有且仅有8个):         1.1 整型:int,short,long,byte(表示一个字节,[-128,127])          1.2 ...

  3. POJ3436 ACM Computer Factory【EK算法】

    题意: 每个电脑需要P个组成部分,现有N的机器,每个机器都可以对电脑进行加工,不过加工的前提是某些部分已经存在,加工后会增加某些部分.且在单位时间内,每个机器的加工都有一个最大加工容量,求能得到的最大 ...

  4. B. Light It Up

    题目链接:http://codeforces.com/problemset/problem/1000/B 代码: #include<iostream> #include<cstrin ...

  5. mysql案例~关于mysql的配置文件个人见解

    mysql 设置参数解读一  mysql的参数分为几类     1 session级别可以设置     2 global级别可以设置     3 session+global级别可以设置     4 ...

  6. 搭建yum服务器

    一.yum服务器端配置1.安装FTP软件#yum install vsftpd #service vsftpd start#chkconfig --add vsftpd#chkconfig vsftp ...

  7. Docker安装ActiveMQ

    ⒈下载 docker pull webcenter/activemq ⒉运行 docker run -d --name myactivemq -p 8161:8161 -p 61613:61613 - ...

  8. 红黑树与AVL树

    概述:本文从排序二叉树作为引子,讲解了红黑树,最后把红黑树和AVL树做了一个比较全面的对比. 1 排序二叉树 排序二叉树是一种特殊结构的二叉树,可以非常方便地对树中所有节点进行排序和检索. 排序二叉树 ...

  9. Expm 2_2 查找中项问题

    对于长度为n的整型数组A,随机生成其数组元素值,然后实现一个线性时间的算法,在该数组中查找其中项. package org.xiu68.exp.exp3; import java.util.Array ...

  10. Java中加密算法介绍及其实现

    1.Base64编码算法 Base64简介 Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法.可查看RFC2045-RF ...