面试题10-二进制中1的个数

思路:

把一个整数和他减1后的数做位于运算,得到的结果(以10进制的整数给出)相当于把原整数的二进制表示中最右端的1变为0,很多问题都可以这么解决。

  • 2的幂 乘2 除2 2的幂指数次放都可以转化为该数的二进制表示方法 左移 右移 二进制中1的个数

  • 整数右移 左移 1位和把整数除2在数学上是一样的,但是除法的效率比移位要低得多,因此实际编程中要尽量多的用移位代替除法

  • 如果是负数移位,因为移位前是个负数,因此保证移位后也要是个负数,所以最高位设为1,如果一直做移位运算,则最后会变成0xffffffff从而变成死循环

  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Thu Feb 23 15:17:01 2017
  4. @author: zzpp220
  5. """
  6. #========除法操作效率低,应换成相应的移位操作,再者,下面的方法输入如果是负数就引起死循环===============================================
  7. #def int2Binary(number):
  8. #    rest_Set=[]
  9. #    while number!=0:
  10. #        rest=number%2
  11. #        rest_Set.insert(0,rest)
  12. #        number=number>>1##除2和右移1位相同
  13. #    return rest_Set.count(1)
  14. #==============================================================================
  15. '''
  16. 输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
  17. '''
  18. class Solution:
  19.    def NumberOf1(self, n):
  20.        count = 0
  21.        if n < 0:
  22.            n = n & 0xffffffff##是先把负数变成整数的表示方法?
  23.         while n:
  24.            count += 1
  25.            #将整数与其减1后的数字做位于,能起到消掉最右边1的效果,循环后,如果整数不为0,那么一共有多少位为1,循环计数就为几
  26.            n = (n-1)&n
  27.        return count
  28. #==============================================================================
  29. # '''
  30. #(-1&0xffffffff)= 4294967295--正数与0xffffffff位与运算最后返回的是10进制的正数形式      
  31. # bin(-1& 0xffffffff)='0b11111111111111111111111111111111'--转化为2进制
  32. #
  33. # type(bin(-1& 0xffffffff))=str
  34. #
  35. # bin(-1& 0xffffffff).count('1')=32
  36. # bin(-32& 0xffffffff).count('1')=27'''
  37. #==============================================================================
  38.    def NumberOf2(self, n):
  39.    ##先得到负数的二进制表示,其实0xffffffff就是-1,所有的负数和-1的二进制做位与,得到其二进制表示
  40.        return bin(n & 0xffffffff).count('1') if n <0 else bin(n).count('1')
  41.    # 判断一个数是不是2得整数次幂
  42.    def powerOf2(self, n):
  43.        if n&(n-1) == 0:##2的幂 乘2 除2 2的幂指数次放都可以转化为该数的二进制表示方法 左移 右移 二进制中1的个数
  44.            return True
  45.        else:
  46.            return False
  47.    # 判断两个数的二进制表示有多少位不一样, 直接比较两个数的二进制异或就可以 如果是整数和负数比较的话要注意
  48.    def andOr(self, m, n):
  49. #====================方法1-变相求整数的二进制表示法中1的个数==========================================================
  50. ##10进制的整数(正数、负数)和0xffffffff都得到其正数的表示方法
  51.        diff = (m&0xffffffff)^(n&0xffffffff)##给出的是10进制的表示,其二进制表示中1的个数就是不同的位数
  52.         count = 0
  53.         while diff:
  54.             count += 1
  55.             diff = diff&(diff-1)##紧接着判断是否满足
  56.         return count
  57. #==============================================================================
  58. #        return bin((m&0xffffffff)^(n&0xffffffff)).count('1')#方法2
  59. S = Solution()
  60. print(S.NumberOf1(-1))
  61. print(S.NumberOf2(-1))
  62. print(S.powerOf2(64))
  63. print(S.powerOf2(63))
  64. print(S.andOr(-1, 1))

附件列表

原文地址:https://www.cnblogs.com/zzxx-myblog/p/6435930.html