轉載自:http://blog.csdn.net/ns_code/article/details/25425577
劍指offer上的第10題,在九度OJ上測試通過。
時間限制:1 秒
內存限制:128 兆
- 題目描述:
-
輸入一個整數,輸出該數二進制表示中1的個數。其中負數用補碼錶示。
- 輸入:
-
輸入可能包含多個測試樣例。
對於每個輸入文件,第一行輸入一個整數T,代表測試樣例的數量。對於每個測試樣例輸入爲一個整數。
。n保證是int範圍內的一個整數。
- 輸出:
-
對應每個測試案例,
輸出一個整數,代表輸入的那個數中1的個數。
- 樣例輸入:
-
3 4 5 -1
- 樣例輸出:
-
1 2 32
無論輸入的是整數還是負數還是0,都可以將該整數和1進行與操作,如果結果不爲0,則表明整數的最低位是1,而後將1左移一位,再次與該證書進行與操作,如果結果不爲0,說明整數的次低位爲1,依次類推,當1移位到變爲0時,統計結束。這種方法需要將1移動32位,也就是需要循環32次。 更好的辦法是利用如下結論: 把一個整數 (無論正負或0)減去1,再和原整數做與運算,會把該整數最右邊的一個1變爲0,例如:110100減1後變爲110011,二者進行與操作後,得到110000,最後邊的1變爲了0,而前面的位都不變。 這樣,我們可以利用這這一結論來從左向右依次將整數的最右邊的1變爲0,當該整數的所有位爲1的位均變爲0之後,便統計到了該整數二進制中1的個數。 AC代碼如下:
- #include<stdio.h>
- #include<stdlib.h>
- int NumOf1(int n)
- {
- int count = 0;
- while(n)
- {
- count++;
- n = n & (n-1);
- }
- return count;
- }
- int main()
- {
- int nums;
- while(scanf("%d",&nums) != EOF)
- {
- int *N = (int *)malloc(nums*sizeof(int));
- if(N == NULL)
- exit(EXIT_FAILURE);
- int i;
- for(i=0;i<nums;i++)
- {
- scanf("%d",N+i);
- printf("%d\n",NumOf1(N[i]));
- }
- }
- return 0;
- }
/**************************************************************
Problem:
1513
User:
mmc_maodun
Language:
C
Result:
Accepted
Time:80
ms
Memory:1304
kb
****************************************************************/