爲了適應邊緣計算的需求決定投入學習Go語言的浪潮,用了10年的java忽然要去接受一個風格徹底不同的語言感受真是太刺激了。 java
最近在看《Go語言聖經》的時候看到裏面的一個計算二進制中1的個數的程序popcount,以爲挺有意思就拿出來分享一下吧。算法
程序代碼總計也沒幾行,能夠說很一目瞭然了:數組
程序分爲兩個部分ide
1, 初始化構造一個長度爲256的數組學習
2, 主程序PopCount經過8次右移操做分別求低8位的1數量而後相加spa
那這麼明顯的結構,這麼清晰的代碼有啥好解讀呢?it
主要緣由是在第一遍看的時候產生了兩個疑問,我以爲有必要記錄一下解決疑惑的過程。class
這個問題須要和PopCount主程序結合看。List
由於在主程序中使用的算法是將64位的無符號整數切割成8個8位,而8位的無符號整數取值範圍是0-255(2^8-1),爲了完整表示這256個數值的1的位數,因此使用了長度爲256的數組。二進制
其實初始化的算法就一句話 pc[i] = pc[i/2] + byte(i&1),一句話就得出了整數中二進制1的個數字典表也太神奇了吧。怎麼來理解這個算法呢?經驗?定理?固然能夠選擇記住就行。
可是咱們仍是能夠嘗試着大聲的念出這段代碼的含義,
對於(整數i的1的個數)等於(整數i/2中1的個數)加上(i在低1位的1的個數)。
是否是有點靈感了?直接上圖吧
從圖中能夠看出每一個整數i的1的個數由兩部分組成
1, i/2的1的個數,這部分就對應算法中的pc[i/2]
2, i/2的餘數,這部分對應算法中的byte[i&1]
到這裏這段代碼的疑惑就所有解開了,嗯就是這麼Go!