劍指Offer算法題-二進(jìn)制中1的個(gè)數(shù)

題目:

請(qǐng)實(shí)現(xiàn)一個(gè)函數(shù),計(jì)算一個(gè)整數(shù)二進(jìn)制表示中1的個(gè)數(shù),例如:把9表示成二進(jìn)制是1001,有2位是1

方案一

判斷該數(shù)最后一位是不是1,然后把該數(shù)右移一位;這樣每次移動(dòng)一位直到這個(gè)數(shù)變?yōu)?為止。但是該思路有個(gè)問(wèn)題就是該數(shù)是負(fù)數(shù)時(shí),會(huì)變成死循環(huán),因?yàn)樨?fù)數(shù)的最高位是1,即使右移之后,為了保證該數(shù)還是負(fù)數(shù),仍會(huì)把最高位置為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)//死循環(huán)

方案二

對(duì)方案一會(huì)產(chǎn)生死循環(huán)的一種改良,把該數(shù)首先與1(即為flag)做&運(yùn)算判斷判斷最低位是否為1,然后把flag左移一位,判斷第二位是否為1,直到flag為0。在4字節(jié)的Int類型里也就是移動(dòng)32次。

extension Int {
    var binaryOneNumber : Int {
        var flag = 1
        var count = 0
        while flag != 0 {
            if flag & self > 0{
                count += 1
            }
            flag = flag << 1
        }
        //如果是負(fù)數(shù)的話,最高位會(huì)統(tǒng)計(jì)不上,這里在加1
        if self < 0 {
            count += 1
        }
        return count
    }
}
print(0.binaryOneNumber) //輸出0
print(9.binaryOneNumber) //輸出2
//這里輸出63是正確的,mac os里Int是64位的,在64位里-9的補(bǔ)碼是
//1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0111
print((-9).binaryOneNumber)//輸出63

方案三

在二進(jìn)制中,把一個(gè)整數(shù)減去1之后再和原來(lái)的整數(shù)做&運(yùn)算,得到的結(jié)果相當(dāng)于把該整數(shù)的二進(jìn)制表示中最右邊的1變成0。因此可以每次都把n & (n - 1)的結(jié)果賦值為n,直到n為0結(jié)束。

extension Int {
    var binaryOneNumber : Int {
        var tmp = self
        var count = 0
        while tmp != 0 {
            //這里減一,不能直接用-,有可能會(huì)有溢出錯(cuò)誤的
            //因?yàn)樨?fù)數(shù)的最大值的補(bǔ)碼形式是1000 0000...,此時(shí)在進(jìn)行減1,就會(huì)有溢出錯(cuò)誤
            tmp = tmp & (tmp &- 1)
            count += 1
        }
    
        return count
    }
}
print(0.binaryOneNumber) //輸出0
print(9.binaryOneNumber) //輸出2
print((-9).binaryOneNumber)//輸出63
print((-1).binaryOneNumber)//輸出64
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容