請編寫一個函數,確定一個整數的計算機內部表示中有幾個“1”。
思索了一下這個題目,我是這樣考慮的,也學書上給出偽代碼
count = 0;
while (這個整數不為0)
{
如果這個整數對2求余的結果是1,則count加1;
將這個整數向右移移位
}
代碼寫出來是這樣的:
int numOnesInBinary(int num)

{
int count = 0;
while (num != 0)
{
if (num % 2 == 1)
count++;
num = num>>1;
}
return count;
}看了一下書中的答案,的確比我簡練很多。對于求余這個方法還是比較笨的。書中采用了邏輯與。
判斷條件從“num%2 == 1”變成 “num&1 == 1”,從程序中更傾向與后者。
所以在分析問題的時候,要學會用邏輯“與、或、異或”進行判斷。
到這一步,看似已經很完美了。但是書中又出奇的給了另一種解法。這種想法我真的沒有想到。
想法的出發點是考慮一個數字減1時,它的二進制發生了什么變化。減1得到的結果是,從最低位的1到最低位都發生了翻轉,其他高位保持不變。如果您對這個整數和減一后的結果進行AND操作,得到的新的數字與原來的整數相比,只有最后一個1變成0.
如果進行多次這樣的操作,這個整數的值變為0。這樣我們也就獲得了這個數的計算機表示中“1”的個數。
int numOnesInBinary2(int num)

{
int count = 0;
while(num != 0)
{
num = num & (num-1);
count++;
}
return count;
}
第一方法的時間復雜度為o(n),第二種的時間復雜度為o(m),m為1的個數。
后記:
最近一周多,一直在做這本書上的編程題。一天3道,自己先嘗試編寫,運行成功后再與書上的解答進行對比。稍有幾次略感比書上稍好些。但大多數情況還是效率差一些。想想原因,還是練得比較少。所以繼續努力。多多積累,養成良好的思維習慣。


