美文网首页算法学习之旅
剑指Offer算法题-二进制中1的个数

剑指Offer算法题-二进制中1的个数

作者: lkkwxy | 来源:发表于2018-09-03 18:46 被阅读0次

    题目:

    请实现一个函数,计算一个整数二进制表示中1的个数,例如:把9表示成二进制是1001,有2位是1

    方案一

    判断该数最后一位是不是1,然后把该数右移一位;这样每次移动一位直到这个数变为0为止。但是该思路有个问题就是该数是负数时,会变成死循环,因为负数的最高位是1,即使右移之后,为了保证该数还是负数,仍会把最高位置为1。

    extension Int {
        var binaryOneNumber : Int {
            var tmp = self
            var count = 0
            while tmp != 0 {
                if tmp & 1 == 1{
                    count += 1
                }
                tmp = tmp >> 1
            }
            return count
        }
    }
    
    print(0.binaryOneNumber) //输出0
    print(9.binaryOneNumber) //输出2
    print((-9).binaryOneNumber)//死循环
    

    方案二

    对方案一会产生死循环的一种改良,把该数首先与1(即为flag)做&运算判断判断最低位是否为1,然后把flag左移一位,判断第二位是否为1,直到flag为0。在4字节的Int类型里也就是移动32次。

    extension Int {
        var binaryOneNumber : Int {
            var flag = 1
            var count = 0
            while flag != 0 {
                if flag & self > 0{
                    count += 1
                }
                flag = flag << 1
            }
            //如果是负数的话,最高位会统计不上,这里在加1
            if self < 0 {
                count += 1
            }
            return count
        }
    }
    print(0.binaryOneNumber) //输出0
    print(9.binaryOneNumber) //输出2
    //这里输出63是正确的,mac os里Int是64位的,在64位里-9的补码是
    //1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0111
    print((-9).binaryOneNumber)//输出63
    

    方案三

    在二进制中,把一个整数减去1之后再和原来的整数做&运算,得到的结果相当于把该整数的二进制表示中最右边的1变成0。因此可以每次都把n & (n - 1)的结果赋值为n,直到n为0结束。

    extension Int {
        var binaryOneNumber : Int {
            var tmp = self
            var count = 0
            while tmp != 0 {
                //这里减一,不能直接用-,有可能会有溢出错误的
                //因为负数的最大值的补码形式是1000 0000...,此时在进行减1,就会有溢出错误
                tmp = tmp & (tmp &- 1)
                count += 1
            }
        
            return count
        }
    }
    print(0.binaryOneNumber) //输出0
    print(9.binaryOneNumber) //输出2
    print((-9).binaryOneNumber)//输出63
    print((-1).binaryOneNumber)//输出64
    

    相关文章

      网友评论

        本文标题:剑指Offer算法题-二进制中1的个数

        本文链接:https://www.haomeiwen.com/subject/slpiwftx.html