为什么这个java递归函数不能正常工作?

时间:2012-02-18 10:25:12

标签: java function recursion

public class cash
{
    public void test(int a)
    {
        if(a<5)
        {
            System.out.print(a+" ");
            test(++a);
            System.out.println(a);
        }
        System.out.println("fin");
    }
    public static void main(String[] argsc)
    {
        cash c=new cash();       
        c.test(1);
    }
}

输出:

1 2 3 4 fin
5
fin
4
fin
3
fin
2
fin
为什么?我认为输出应该是1 2 3 4 fin。 非常感谢你。

9 个答案:

答案 0 :(得分:4)

好的,这是你的递归方法:

public void test(int a)
{
    if(a<5)
    {
        System.out.print(a+" ");
        test(++a);
        System.out.println(a);
    }
    System.out.println("fin");
}

调用此方法时,每个语句都会被调用。让我们考虑一下这种方法中的语义。 此列表用文字描述了您的方法的作用:

  • 检查是否<5。如果是真的
    • 打印出来。
    • 致电test(++a)
    • 打印出增加的
  • 打印出"fin"

您的第一个问题是,您始终(在test()的每次调用期间)打印出"fin"。把它放在else {...}块中以修复它。

你的第二个问题是,你打印出增加的a值,这就是你获得输出的原因。删除第二个println语句(System.out.println(a);)来修复它。

您的方法的正确实现如下所示:

public void test(int a)
{
    if(a<5) {
        System.out.print(a);
        test(++a);
    } else {
        System.out.println("fin");
    }
}

答案 1 :(得分:2)

试试这个:

public class cash
{
    public void test(int a)
    {
        if(a<5)
        {
            System.out.print(a+" ");
            test(++a);
            return;
        }
        System.out.println("fin");
    }
    public static void main(String[] argsc)
    {
        cash c=new cash();       
        c.test(1);
    }
}

注意:上面的代码尚未经过测试。

修改

您的代码在达到a=5后没有停止条件;因此,在递归调用自身之后的System.out.print行总是在弹出堆栈时执行;因此输出:

1
2
3
4 -- function stops calling itself here and returns. Stack is popped
fin -- Program continues executing the line from the last recursive call (prints fin)
5 --  As above, there were 2 lines pending to execute from the previous call, the system.out.println after test(a++) 
fin  -- And the system.out.println('fin');
4  -- Stack is popped, same 2 lines as above. prints 4 since the value of a when the function was called was 4 then continues on to the next line, which prints 'fin' 
fin
... and so on

答案 2 :(得分:1)

这是您的代码将执行的内容:

test(1); // Outputs "1", calls test(2), outputs "2" and "fin" after that
test(2); // Outputs "2", calls test(3), outputs "3" and "fin" after that
test(3); // Outputs "3", calls test(4), outputs "4" and "fin" after that
test(4); // Outputs "4", calls test(5), outputs "5" and "fin" after that
test(5); // Outputs "fin" after that

基本上:

"1 " + test(2) + "2" + "fin"
"1" + ("2" + test(3) + "3" + "fin") + "2" + "fin"
"1" + ("2" + ("3" + test(4) + "4" + "fin") + "3" + "fin") + "2" + "fin"
"1" + ("2" + ("3" + ("4" + test(5) + "5" + "fin") + "4" + "fin") + "3" + "fin") + "2" + "fin"
"1" + ("2" + ("3" + ("4" + ("fin") + "5" + "fin") + "4" + "fin") + "3" + "fin") + "2" + "fin"

所以你的输出是正确的。

答案 3 :(得分:0)

NO! o / p是正确的...... test(++a)将一次又一次地调用自己,直到a = 5 ......一旦完成,只有在此之后它才会打印下一行的其他值..

试验(5) - &GT;试验(4) - &GT;试验(3) - &GT;试验(2) - &GT;试验(1)

递归函数使用stack ...所以最后一个将首先出来......

看一看here .....

答案 4 :(得分:0)

这是使用调试器很有用的地方。你可以看到,当它解除递归时,每次都会抛出fin,而不仅仅是当你决定停止时。

答案 5 :(得分:0)

你在递归中做的第一件事是打印元素,然后递归调用函数。

让我们看一下递归的调用堆栈。 [我们将通过其参数a]

表示每个递归调用

首先,您只使用一个元素

调用该方法
| |
|1|
---

你将打印“1”并用2调用递归调用,现在顶部将是:

|2|
|1|
---

再次输入方法并打印元素2,然后使用3重新调用,并获取:

|3|
|2|
|1|
---

继续这个逻辑,你将最终打印1,2,3,4,并获得堆栈跟踪:

|5|
|4|
|3|
|2|
|1|
---

现在,条件不符合,所以你只打印fin,并返回 - 导致弹出第一个元素:

|4|
|3|
|2|
|1|
---

当你从递归调用回来时,打印顶部+ 1 [5]然后打印fin,然后再次从堆栈跟踪的头部弹出元素,并得到:

|3|
|2|
|1|
---

现在再次打印头+ 1:4fin,再弹出一个元素....
继续这个逻辑,直到堆栈为空,你就得到了程序打印的内容!

答案 6 :(得分:0)

尝试以下代码......您将了解此程序的运行方式

public class cash
{
    public void test(int a)
    {
    if(a<5)
    {
        System.out.print(a+" ");
        System.out.print("test 1 - " + a);
        test(++a);
        System.out.print("test 2 - " + a);
        System.out.println(a);
    }
    System.out.println("fin");
    }
    public static void main(String[] argsc)
    {
    cash c=new cash();       
    c.test(1);
    }
}

更新1

要获得所需内容,请使用下面的

public class cash
{
    public void test(int a)
    {
    if(a<5)
    {
        System.out.print(a+" ");
//            System.out.print("test 1 - " + a);
        test(++a);
        if (a==5)
        System.exit(0);
//            System.out.print("test 2 - " + a);
        System.out.println(a);
    } else {
    System.out.println("fin");
    }
    }
    public static void main(String[] argsc)
    {
    cash c=new cash();       
    c.test(1);
    }
}

答案 7 :(得分:0)

在第四次递归调用测试方法期间,在调用方法(test(++ a))之前,a变量会增加到5。因为&lt; 5是假的,它将继续印刷鳍并返回(因此你的输出:1 2 3 4 fin)

然而,在返回后不久,它将继续执行其余的代码,将打印5,然后是fin。对于代码中任何先前的递归迭代,同样的事情一直在继续,因此递归输出:X fin(其中X是每个前一次迭代中a的值)

答案 8 :(得分:0)

您的解决方案中的问题是递归的退出条件(a大于或等于5)正在执行始终。它应该只执行一次,第一次条件成立 - 所以你必须将它放在else块中。另外,分配参数(++a部分)是个坏主意。

我能想到编写test方法的最简单方法是:

public void test(int a) {
    if (a < 5) {
        System.out.print(a + " ");
        test(a + 1);
    } else {
        System.out.println("fin");
    }
}