統計二進制1個數的代碼解讀

爲了適應邊緣計算的需求決定投入學習Go語言的浪潮,用了10年的java忽然要去接受一個風格徹底不同的語言感受真是太刺激了。 java

最近在看《Go語言聖經》的時候看到裏面的一個計算二進制中1的個數的程序popcount,以爲挺有意思就拿出來分享一下吧。算法

 

程序代碼總計也沒幾行,能夠說很一目瞭然了:數組

image.png

程序分爲兩個部分ide

1, 初始化構造一個長度爲256的數組學習

2, 主程序PopCount經過8次右移操做分別求低8位的1數量而後相加spa

 

那這麼明顯的結構,這麼清晰的代碼有啥好解讀呢?it

主要緣由是在第一遍看的時候產生了兩個疑問,我以爲有必要記錄一下解決疑惑的過程。class

 

初始化數組爲何是256

這個問題須要和PopCount主程序結合看。List

由於在主程序中使用的算法是將64位的無符號整數切割成88位,而8位的無符號整數取值範圍是0-2552^8-1),爲了完整表示這256個數值的1的位數,因此使用了長度爲256的數組。二進制

初始化算法的依據是什麼

其實初始化的算法就一句話 pc[i] = pc[i/2] + byte(i&1),一句話就得出了整數中二進制1的個數字典表也太神奇了吧。怎麼來理解這個算法呢?經驗?定理?固然能夠選擇記住就行。

 

可是咱們仍是能夠嘗試着大聲的念出這段代碼的含義,

對於(整數i1的個數)等於(整數i/21的個數)加上(i在低1位的1的個數)。

是否是有點靈感了?直接上圖吧

image.png

從圖中能夠看出每一個整數i1的個數由兩部分組成

1, i/21的個數,這部分就對應算法中的pc[i/2]

2, i/2的餘數,這部分對應算法中的byte[i&1]

 

到這裏這段代碼的疑惑就所有解開了,嗯就是這麼Go

相關文章
相關標籤/搜索