返回void搞乱参考参数值

时间:2012-12-27 15:45:01

标签: java return pass-by-reference void

我编写此代码的目的是每次调用recurse()时链都会递增。但是,每当recurse()到达返回时,它(从我用调试器看到的内容)执行此操作,它会递减b的值。如果您想了解我正在尝试做的事情,那么这就是项目征集#14。

http://projecteuler.net/problem=14

private static void euler14()
{
    int currentstart=1000000;
    int longest = 0;
    int current=0;
    Integer chain=0;
    for(int i = currentstart; i>0; i--)
    {
        recurse(i,chain);
        if(chain > current)
        {
            current=chain;
            longest=i;
        }
        chain = 0;
    }
    System.out.print("Euler 14: " + longest + "\n");
}

private static void recurse(int a, Integer b)
{
    b++;
    if(a==1)
    {
        return;
    }
    else if(a%2==0)
    {
        recurse((a/2), b);
    }
    else if(a%2==1)
    {
        recurse(((a*3)+1), b);
    }
    return;

}

3 个答案:

答案 0 :(得分:5)

尽管对Integer的引用(按值)传递给recurse,但对象本身是不可变的。执行b++后,递增的值将分配给brecurseb的本地值。返回后,该值将返回到调用者中b的未更改副本。

您可以将static int变为recurse变量,并将其从private static int b = 0; private static void recurse(int a) { b++; if(a==1) { return; } if(a%2==0) { recurse((a/2), b); } else if(a%2==1) { recurse(((a*3)+1), b); } } 的参数列表中删除以解决问题:

{{1}}

答案 1 :(得分:2)

要查看主要方法中b的更新,当您到达递归结束时,需要将其返回:

private static int recurse(int a, int b) {
    b++;
    if(a==1) return b;
    else if(a%2==0) return recurse((a/2), b);
    else if(a%2==1) return recurse(((a*3)+1), b);
    return b;
}

在您的主要方法中,您使用新值更新chain

chain = recurse(i,chain);

答案 2 :(得分:2)

由于您的方法当前没有返回值,因此您可以使用返回值作为步骤数。只需在每个递归步骤中添加1:

private static int recurse(int a) {
    if(a==1) {
        return 1;
    }
    if(a%2==0) {
        return 1 + recurse(a/2);
    } else if(a%2==1) {
        return 1 + recurse((a*3)+1);
    }
}