关闭

二进制中有多少个1

标签: 位运算二进制
869人阅读 评论(0) 收藏 举报
分类:

题目描述:计算在一个 32 位的整数的二进制表式中有多少个 1.

样例:给定 32 (100000),返回 1;给定 5 (101),返回 2;给定 1023 (111111111),返回 9

很简单的题目,当然可以先对十进制的整数转换成二进制,再统计1的个数。

但是通过位运算(其实就是通过分析二进制位上0,1的关系,直接对0,1比特位进行运算)我们可以更快地解决问题。

先说一下基本的几种位运算:

1. 与(&):相当于是数学关系中的交,只有全部为真,结果才是真,也就是说,

0 & 1 = 1 & 0 = 0 & 0 = 0; 

1 & 1 = 1 

2. 或(|):相当于求并,有一个真就是真,

0 | 0 = 0

1 | 0 = 0 | 1 = 1 | 1 = 1

3. 异或(^):相同则假,相异则真,

1 ^ 1 = 0 ^ 0 = 0

1 ^ 0 = 0 ^ 1 = 1


当然,还有右移和左移运算,这里不做详细介绍了。以后有机会再同大家分享。

回头看这道题,要统计的是整数的二进制中有多少个1. 那么可以考虑一下这个问题,就是整数和它减去1后的数相比,在二进制的形式中,有什么关系呢?

我发现,有以下两条:

1. 奇数的话,减去1成偶数,二进制形式中,只有最后一位不同(由1变为0)。例如:5:101,4:100

2. 偶数的话,减去1成奇数,二进制形式中,偶数尾巴上的所有0(直到倒数第一个1为止),全部变为1,且倒数第一个1变为0. 例如:142:10100000;141:10011111

好了,这就算是找到规律了,这个规律怎么用呢?我发现,用“与”运算可以产生很奇妙的效果:不论是奇数还是偶数,“与”运算之后,都会是原先的数的二进制中少一个1.

那么思路很清晰了,写一个循环,每次都和减1的值做“与”运算,直到结果等于0,统计循环的次数,就能知道有多少1.

代码如下:

class Solution:
    # @param num: an integer
    # @return: an integer, the number of ones in num
    def countOnes(self, num):
        count = 0
        temp = num
        if num < 0:
            temp = abs(num + 1)
        while temp != 0:
            count += 1
            temp = temp & (temp - 1)
        return count if num >= 0 else (32 - count)
        # write your code here


需要注意的是正负数的二进制问题。7-8行是对负数做的处理。这里,先普及一下负数的二进制是如何生成的,分两步:

1. 取反:就是对这个负数的绝对值按位取反,得到的叫做反码(比如,要计算-2的二进制,就要先对2的二进制按位取反)

2. 加1:取反后,对这个二进制数加1,得到的叫做补码

比如,-24,先对24(二进制数:11000)取反,得到00111;再加1,得到01000

所以,我们设一个负数是a,显然,a - 1的二进制表示就是-a的反码。而用32减去(-a)中1的个数就是(a - 1)中1的个数。因此,求一个负数的二进制中1的个数,可以先对这个数(把他看做a - 1)加1,记为b,再求b的绝对值的二进制表示的1的个数,记为n,32 - n就是最后的答案。

上面的逻辑稍微有点绕,不过仔细想想应该能明白。

0
0
查看评论

判断一个整数的二进制位中有多少个1

// 判断一个整数的二进制位中有多少个1void totalOne(int x){ int count = 0; while(x) { x = x & ( x - 1 ); count++; } printf("count = %d/n", count);}循环: ...
  • ameyume
  • ameyume
  • 2010-05-18 12:59
  • 7843

-1的二进制表示

虽然一直用C/C++,但很少涉及到Bit序列的问题。比如,-1的二进制表示到底是怎样的?从没有深究过,一直都是模棱两可的,说出来实在让人笑话。 对于有符号整型数的简单认识就是,最高位为符号位,0为正,1为负,那么剩下几位应该如何表示呢?理所当然的认为,既然是1表示为0000 0001(假设为8位整...
  • optman
  • optman
  • 2009-02-12 17:13
  • 16389

二进制中1的位置

1.题目   给出一个正整数n, 打印出它的二进制中所有1的位置。二进制中最低位的位置是0,从右往左数,位置序号依次递增。例如,正整数13的二进制(1101)中1的位置为0,2,3。 2.输入   输入数据的第一行是一个正整数d, 表示这个数据集中正整数的个数,1≤d≤10。数据集 列在d的下...
  • sanqima
  • sanqima
  • 2015-09-15 13:02
  • 919

二进制中有多少个1

问题: 计算在一个 32 位的整数的二进制表式中有多少个 1。 样例: 给定 32 (100000),返回 1。 给定 5 (101),返回 2。 给定 1023 (111111111),返回 9。 分析: 1、需要考虑是负数的情况,如果是负数,则二进制的第一位为1,首先需要处理这个1...
  • hpingwu
  • hpingwu
  • 2015-11-05 20:41
  • 1555

二进制中有多少个1

计算在一个 32 位的整数的二进制表式中有多少个 1. 样例 给定 32 (100000),返回 1 给定 5 (101),返回 2 给定 1023 (111111111),返回 9 ...
  • chriscute
  • chriscute
  • 2016-10-25 11:17
  • 129

<LeetCode> 题365:二进制中有多少个1

题目描述:计算在一个 32 位的整数的二进制表式中有多少个 1. 例如: 给定 32 (100000),返回 1 给定 5 (101),返回 2 给定 1023 (111111111),返回 9思路1:将1不断左移,再与n相与(&)例如:要求5的二进制中有多少个1,就需要让5(101...
  • u013003827
  • u013003827
  • 2016-07-21 14:34
  • 416

Lintcode 二进制中有多少个1

计算在一个 32 位的整数的二进制表式中有多少个 1. 您在真实的面试中是否遇到过这个题?  Yes 样例 给定 32 (100000),返回 1 给定 5 (101),返回 2 给定 102...
  • Hk_john
  • Hk_john
  • 2017-04-17 15:38
  • 436

二进制中有多少个1

计算一个十进制数转为二进制后有多少个1(或者0) 样例: 给定32(100000)返回1 给定5(101)返回2 分析 方法一:普通法 public int countOnes1(int num){ int count = 0; while(num...
  • zy512638348
  • zy512638348
  • 2017-10-21 15:28
  • 114

判断一个数的二进制有多少个1

常规方法:       c = a ^ b       cnt = 0       while c:             if c &am...
  • xys228280987
  • xys228280987
  • 2015-09-24 17:55
  • 139

快速的判断一个数的二进制中有多少个1

x=x&(x-1)   表达式的意思就是:把x的二进制表示从低位开始,将遇到的第一个为1的比特位 置0。 例如: e1: x = 01001000 x-1 = 01000111 x&(x-1)=01000000 e2: x = 01001001 x-1 = 010...
  • qq_20801369
  • qq_20801369
  • 2016-09-03 19:11
  • 2305
    个人资料
    • 访问:203177次
    • 积分:4085
    • 等级:
    • 排名:第8992名
    • 原创:212篇
    • 转载:0篇
    • 译文:0篇
    • 评论:39条
    博客专栏
    文章分类
    最新评论