题目描述

输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

解题思路

根据题意我们只需要将 n 与 1 进行相与运算,看结果是不是 0,然后再将 n 右移,再循环上述步骤直到 n=0 为止。看起来是这样,但是这样做存在一定的问题。因为题目中明确说出 n 可能为负数,如果将负数右移,那么高位会被符号 1 填充,这就导致结果不正确。不过在 Java 中,可以使用“>>>”进行无符号右移。
不过还有一个简便的方式就是把整数减去 1,再与原整数做与运算,会把该整数最后边一个 1 变成 0。这样满足要求的原因是与运算特质是 1 & 1 = 1; 其他情况都为 0。

代码实现

  1. import java.util.Scanner;
  2. public class Problem11 {
  3. public static int NumberOf1(int n) {
  4. int ans = 0;
  5. while(n != 0) {
  6. n &= (n - 1);
  7. ans ++;
  8. }
  9. return ans;
  10. }
  11. public static int NumberOf2(int n) {
  12. int cnt = 0;
  13. while(n!=0){
  14. if((n&1)!=0)
  15. cnt++;
  16. n=n>>>1; //java没有unsigned关键字,>>>就是java中的无符号右移
  17. }
  18. return cnt;
  19. }
  20. public static void main(String[] args) {
  21. Scanner cin = new Scanner(System.in);
  22. int n = cin.nextInt();
  23. System.out.println(NumberOf1(n));
  24. }
  25. }