【问题标题】:Java boolean-algorithm to check wheter number of digits is evenJava布尔算法检查位数是否为偶数
【发布时间】:2025-12-29 04:10:06
【问题描述】:

我正在尝试编写一个递归方法,如果显示为二进制数的 n 的位数是偶数,则返回 true,如果它是奇数,则返回 false。 如果递归方法返回布尔值,我真的不明白如何计算递归方法。

我认为部分解决方案是,检查数字是否是 2 的幂:

static boolean isPowers2(long n) {
    if (n % 2 != 0) return false;
    if (n / 2 == 1) return true;
    return isPowers2(n / 2);
}

如果指数是奇数,那么位数是偶数,如果是偶数,那么位数是不均匀的。但是我不能用我的布尔函数传递一个值,对吧?

应该返回的一些示例:

  // evenCount(0B0    ) is false
  // evenCount(0B1    ) is false
  // evenCount(0B10   ) is true
  // evenCount(0B11   ) is true
  // evenCount(0B100  ) is false
  // evenCount(0B111  ) is false
  // evenCount(0B1000 ) is true
  // evenCount(0B1010 ) is true
  // evenCount(0B10000) is false
  // evenCount(0B10110) istfalse

这是我在大学的算法测试中失败的一个问题,我仍然不知道如何解决它。我希望有人能给我一个关于如何解决这个问题的提示......

【问题讨论】:

  • 为什么你认为 0 的位数是奇数?
  • @Nelfeal:你会如何显示 0?我会显示一个数字,一个“0”。一位是奇数。

标签: java algorithm recursion boolean digits


【解决方案1】:

检查输入是否为 2 的幂是无关紧要的。您应该编写一个递归方法,在每次调用中删除一位。

一个数字只有在去掉一位的情况下才具有奇数长度时才具有偶数二进制长度。

static boolean hasEvenLength(int n)
{
    if (n<2) { // single digit
        return false;
    }
    return !hasEvenLength(n/2);
}

这处理非负输入。对于负数,我认为你应该总是返回 true,因为最高有效位(符号位)总是被设置,所以你可以说这个数字有 32 个二进制数字。

这是 0 到 99 之间所有数字的方法的输出:

0 0 false
1 1 false
2 10 true
3 11 true
4 100 false
5 101 false
6 110 false
7 111 false
8 1000 true
9 1001 true
10 1010 true
11 1011 true
12 1100 true
13 1101 true
14 1110 true
15 1111 true
16 10000 false
17 10001 false
18 10010 false
19 10011 false
20 10100 false
21 10101 false
22 10110 false
23 10111 false
24 11000 false
25 11001 false
26 11010 false
27 11011 false
28 11100 false
29 11101 false
30 11110 false
31 11111 false
32 100000 true
33 100001 true
34 100010 true
35 100011 true
36 100100 true
37 100101 true
38 100110 true
39 100111 true
40 101000 true
41 101001 true
42 101010 true
43 101011 true
44 101100 true
45 101101 true
46 101110 true
47 101111 true
48 110000 true
49 110001 true
50 110010 true
51 110011 true
52 110100 true
53 110101 true
54 110110 true
55 110111 true
56 111000 true
57 111001 true
58 111010 true
59 111011 true
60 111100 true
61 111101 true
62 111110 true
63 111111 true
64 1000000 false
65 1000001 false
66 1000010 false
67 1000011 false
68 1000100 false
69 1000101 false
70 1000110 false
71 1000111 false
72 1001000 false
73 1001001 false
74 1001010 false
75 1001011 false
76 1001100 false
77 1001101 false
78 1001110 false
79 1001111 false
80 1010000 false
81 1010001 false
82 1010010 false
83 1010011 false
84 1010100 false
85 1010101 false
86 1010110 false
87 1010111 false
88 1011000 false
89 1011001 false
90 1011010 false
91 1011011 false
92 1011100 false
93 1011101 false
94 1011110 false
95 1011111 false
96 1100000 false
97 1100001 false
98 1100010 false
99 1100011 false

【讨论】:

  • 好答案!如果你想支持负数,我认为你可以检查Math.abs(n) &lt; 2,然后使用n &gt;&gt; 1而不是n / 2
  • @JacobG。实际上,我可以争辩说,对于负数,您应该始终返回 true,因为最高有效位是 1,所以该数字有 32 位。
  • 这是真的,假设 OP 的意图不是用负数翻转 1 和 0 的含义。无论如何,可能超出了这个问题的范围。
  • 哇,谢谢!解决方案比我想象的要短得多......还有一个问题:我知道我必须一次删除一个数字。我仍然卡住的是递归调用。这意味着我每次删除一个数字时都会在真假之间交替,对吧?
【解决方案2】:

您不需要计算数字,您只需要跟踪该计数是奇数还是偶数。

boolean hasEvenDigitCount(long n) {
    if (n/2 == 0) { // handles both 1 and 0 as an even number of digits
        return false;
    }
    return !hasEvenDigitCount(n/2);
}

【讨论】:

    【解决方案3】:

    虽然 Nelfeal 和 Eran 的解决方案很好,但我想提一个通用方法,同时解决递归问题,即将中间结果作为附加参数。

     def isEvenLength (n: Long) : Boolean = {
    
         def isEvenLength (n: Long, sofar: Boolean) : Boolean = {
             if (n < 2) sofar else isEvenLength (n/2, !sofar) 
         } 
    
         isEvenLength (n, false) 
     }
    

    我认为内部函数还没有到达 Java,所以在 Pseudo-Java 中,它看起来更像这样:

     static boolean isEvenLength (final long n, final boolean sofar) {
         if (n < 2) sofar else isEvenLength (n/2, !sofar);
     } 
    
     static boolean isEvenLength (final long n) {
         isEvenLength (n, false);
     }
    

    所以计算长度可以通过在 sofar 上加一来完成

     if (n < 2) sofar else isEvenLength (n/2, sofar+1)
    

    使用(希望)int 作为 sofar 的类型。

    【讨论】:

      【解决方案4】:

      作为一个黑客技巧,您可以在 java 中使用它(速度无效):

      static boolean hasEvenLength(int n) {
          return Long.toBinaryString(n).length() % 2 == 0;
      }
      

      【讨论】: