递归乘法方法正确的思考方式吗?

时间:2016-05-13 18:17:44

标签: java recursion

    public static void main(String[]args){
multiply(2,4);

}
public static int multiply(int a, int b) {
       if (b == 0) {
          return 0;
       }
       return a + multiply(a, b - 1);
    }
}

我有这个递归声明,我想知道它是如何工作的,这是正确的思考方式吗?

return 2 + (2, 3);
return 2 + (2,2);
return 2 + (2,1);
return 2 + (2,0);

return 2 + 6;
return 2 + 4;
return 2 + 2;
return 2 + 0;

3 个答案:

答案 0 :(得分:3)

最简单的方法是尝试:

public static int multiply(int a, int b) {
       System.out.println("-->multiply("+a+", "+b+")");
       if (b == 0) {
          System.out.println("<--returning zero for "+a+"*"+b);
          return 0;
       }
       int ret = a + multiply(a, b - 1);
       System.out.println("<--returning "+a+"*"+b+" = "+ret);
       return ret;
}

您的输出将是:

-->multiply(2, 4)
-->multiply(2, 3)
-->multiply(2, 2)
-->multiply(2, 1)
-->multiply(2, 0)
<--returning zero for 2*0
<--returning 2*1 = 2
<--returning 2*2 = 4
<--returning 2*3 = 6
<--returning 2*4 = 8

箭头显示堆栈何时增长(-->)以及何时收缩(<--)。这是一种有用的技术,通常可视化递归调用:在输入方法后记录输入,并在返回之前记录结果。

答案 1 :(得分:2)

我对你所展示的内容并不十分清楚,虽然它看起来相当正确(如果我正确地解释它)。您需要完成方法的每次调用,直到您遇到基本情况(在本例中,它是b == 0时)。然后,您可以重新开始工作,替换返回的值。

multiply(2,4)返回2 + multiply(2,3)multiply(2,3)返回2 + multiply(2,2)multiply(2,2)返回2 + multiply(2,1)multiply(2,1)返回2 + multiply(2,0)multiply(2,0)会返回0

所以,如果我们用返回值替换,从下往上工作,你得到:

return 2 + 2 + 2 + 2 + 0;

等于82 x 4 = 8

答案 2 :(得分:2)

你几乎是完美的,只是......请记住,对于我们这些可怜的人来说,返回似乎对于我们倾向于考虑它们的人来说,要恢复指令的顺序。
因此:
,在分析嵌套的调用时,您完全正确 NO ,你在分析返回时犯了错误,这是按照以下顺序发生的(与你的感觉相比还原,但如果你考虑返回LAST函数调用,这是有道理的第一): Returning: 2+0 Returning: 2+2 Returning: 2+4 Returning: 2+6 由于一般解决方案优于特定解决方案,因此以下是您的原始程序,它使用了2个额外的printfs()和一个额外的变量(res)。您可以通过这种方式跟踪任何重复。 :-) public static void main(String[] args){ multiply(2,4); } public static int multiply(int a, int b) { int res; if (b == 0) { return 0; } System.out.printf("Calling: %d+multiply(%d, %d)\n", a, a, b-1); res = multiply(a, b - 1); System.out.printf("Returning: %d+%d\n", a, res); return a + res; }