傳統的求二進制中1的個數的方法就不說了,複雜度爲O(logx),x爲要求的數,即要遍歷全部的位數作統計。算法
看一個效率較高的算法。編程
int count(int x) { int num=0; while(x) { num += x & 0x01; x>>=1; } return num; }
改算法每次和1作&操做,若是爲1,則最後一位爲1,不然爲0.採用位操做符明顯提升了效率,可是複雜度依然爲O(logx).學習
下降複雜度的算法spa
int count(int x) { int num=0; while(x) { x &= (x-1); num++; } return num; }
看似簡單的代碼,其實乍一看仍是看不懂。分析一下。code
既然咱們要統計二進制中爲1的數,那麼就不必管那些二進制位0的位了。class
假如一個數x=01101000,那麼x-1就是01100111,就是說x從最後一位向前找到第一個位數爲1的二進制(1000),減1以後前面的不變,變的是後面(0111),也就是說從第一個爲1的那一位開始(包含爲1的那一位),減1以後就至關於取反。再與原來的x作&操做,1000&0111=0000,即從後向前依次把第一個1變爲0,就能夠統計出1的個數。效率
而且該算法的複雜度只與1的個數有關。擴展
擴展問題:給定兩個數A和B,統計兩個數中有多少位是不一樣的?書籍
想法:A和B作亦或運算獲得的數x,再統計x二進制中1的個數。遍歷
你們有好的想法能夠留言,也讓我學習一下。
參考書籍:編程之美