所以我的方法适用于计算一些奇数但不是全部的1的数量,我需要确定偶数个二进制数中有多少1。这就是我到目前为止所做的:
if (n == 1){
return count+1;
}
else{
count = count + 1;
return numOnes(n/2, count);
}
还可以将count声明为递归方法的实例变量吗?当递归方法时,它如何保持计数。
答案 0 :(得分:2)
你使用偶数(以及可能是某些奇数)失败的原因是因为你的递归没有适当的基本情况。解决方案非常简单:添加另一个基本情况,其中n == 0。
关于你的第二个问题 - 在Java中,每次调用一个方法时,该方法的信息都放在调用堆栈上。如果在方法中声明 中的任何变量,则该信息对于每个递归调用都是唯一的。例如,如果在递归方法中声明int count = 0
,则每次调用该方法时都会创建一个新的count
变量。通常,程序员甚至不会使用局部变量:
//Base cases return specific values
return recursiveCall(newParameters);
使用您的问题,您可以尝试类似:
private int numOnes(int n){
if(n < 2){
return n; //returns 0 for 0, and 1 for 1.
}
int ones = 0;
ones += (ones % 2 == 0) ? 0 : 1; // adds one if number is odd.
ones += numOnes(n/2); //chops off last digit, recomputes.
return ones;
}
我们的想法是,我们一次查看每个位(通过检查数字是否为奇数),然后切断该位并查看其余位。基本情况是,如果我们只剩下一个数字(或者我们剩下的所有数字都是0)。另请注意,您必须使用特殊代码来处理负值(我会将该部分留给您)。
答案 1 :(得分:0)
这很容易,但是在最小整数值处有一个小皱纹,我们知道它将有二十二个二进制,因为它的2 ^ 31表示为两个&#39; s补。
我建议您首先使用一些测试用例来解决问题:
@Test
public void should_be_0_ones_in_zero() {
assertEquals(0, Ones.count(0));
}
@Test
public void should_be_1_one_in_one() {
assertEquals(1, Ones.count(1));
}
@Test
public void should_be_1_one_in_two() {
assertEquals(1, Ones.count(2));
}
@Test
public void should_be_4_ones_in_fifteen() {
assertEquals(4, Ones.count(15));
}
@Test
public void should_be_31_ones_in_max_integer() {
assertEquals(31, Ones.count(Integer.MAX_VALUE));
}
处理正整数非常简单。
static class Ones {
static int count(int n) {
if (n < 2) return n;
return (n & 1) + count(n >> 1);
}
}
这里的表达式为:
(n&amp; 1)
描述最低有效位的一个 - 即,它是0或1.我们捕获结果计数,然后继续递归剩余的位(符号位除外):
n&gt;&gt; 1
我认为你也有兴趣处理负值,例如这个......
@Test
public void should_be_2_ones_in_negative_one() {
assertEquals(2, Ones.count(-1));
}
和这一个!
@Test
public void should_be_32_ones_in_min_integer() {
assertEquals(32, Ones.count(Integer.MIN_VALUE));
}
目前,除了明确检查之外,我没有更好的办法处理Integer.MIN_VALUE。
static class Ones {
static int count(int n) {
if (n == Integer.MIN_VALUE) return 32;
if (n < 0) return 1 + countForPositive(-1 * n);
return countForPositive(n);
}
// expect disappointing results for negative values of n, such
// as Math.abs(Integer.MIN_VALUE)--yes, really!
static int countForPositive(int n) {
if (n < 2) return n;
return (n & 1) + countForPositive(n >> 1);
}
}
对于负数,只需添加1即可考虑符号位。希望它有所帮助!