TAG
位操作
漢明重量 HammingWeight
方法
非常有背景的一道題。
詳細見維基百科-漢明重量 or Wikipedia-Hamming Weight
總的來說,這是經典的“漢明距離(Hamming Weight)”問題,由於在密碼學、編碼理論、信息論中常用到計算數據位中1的個數,所以有的CPU(X86)是有單獨的指令(popcnt
)來做這個操作的,GCC下有函數__builtin_popcount(unsigned int x)
, MSVC下有__popcnt(unsigned int value)
(
代碼
class Solution {
public:
int hammingWeight(uint32_t n) {
int oneBitCnt = 0 ;
while(n)
{
if( (n & 1) == 1 ) { ++ oneBitCnt ;}
n = n >> 1 ;
}
return oneBitCnt ;
}
};
後記
上述代碼實現是算是最LOW的方法,時間消耗上與使用__builtin_popcount(unsigned)
方法相同(leetcode平臺),耗時8ms;使用標準庫std::bitset<32>(n).count()
耗時4ms。
最後,上述代碼有改進空間,就是去掉if語句: oneBitCnt += n & 1
理論上去掉if
是更好的選擇…我看維基百科中甚至有把循環展開寫的…
! 結果更新,當我去掉if後,耗時變爲4ms!當然,我不知道背後發生了什麼… 不知道是if給流水帶來的影響,還是編譯器的優化.
說起優化,想起之前看到的一句話——不懂原理的優化簡直就是邪惡。所以,咱們暫時就這麼寫着,以後也不必刻意在乎if是否存在… 因爲這種層次上優化,往往需要深厚的對編譯的理解。此刻我還不懂,也暫時不必深究。