练习java递归

练习java递归,java,recursion,Java,Recursion,我不明白这个练习如何返回数字的平方。特别是我不理解第六行,其中有return语句,后面是“+2*x-1”。该调用中的程序行为是什么 public class Es { public static int RecCalc(int x) { if (x==0) { return 0; }else { return RecCalc(x - 1) + 2 * x - 1; } } p

我不明白这个练习如何返回数字的平方。特别是我不理解第六行,其中有return语句,后面是“+2*x-1”。该调用中的程序行为是什么

public class Es {
    public static int RecCalc(int x) {
        if (x==0) {
            return 0;
        }else {
            return RecCalc(x - 1) + 2 * x - 1;
        }
    }

    public static void main(String[] args) {
        System.out.println(RecCalc(3));
    }
}

我们可以通过一点代数来了解这一点:

(x-1)² + 2x - 1
== x² - 2x + 1 + 2x - 1
== x²

如果您不熟悉
(x+y)²
的公式,则可以通过将其写成
(x-1)*(x-1)
并使用或分配属性来执行
(x-1)²
。这是留给读者的练习。

如果你有4件东西,你可以用第2面做一个正方形:

xx
xx
如果你想用边3做一个正方形,你需要9样东西:在边和底各加2样东西,在角上加1样东西:

xx.
xx.
..+
或者,换一种说法,在侧面和底部各添加3件物品,在拐角处添加1件物品

一般来说,如果你有一个边长的平方(n-1),要得到一个边长的平方(n),你必须加上两个(n-1)的东西,再加上一个;或者两(n)件东西,拿走一件

因此:

    number of things in a square of side length n

=  (number of things in a square of side length (n-1))
   + 2 * (n-1) + 1

=  (number of things in a square of side length (n-1))
   + 2 * n - 1

让我们一步一个脚印,一次打一个电话

启动这一切的第一个电话是:

RecCalc(3);
在Java中,return语句将把所有内容都带到分号。 因此,
return3+2
将向调用者返回5

RecCalc(3)将导致调用: RecCalc(2)+2*3-1

RecCalc(2)将导致调用: RecCalc(1)+2*2-1

RecCalc(1)将导致调用: RecCalc(0)+2*1-1

RecCalc(0)将返回0

现在我们可以用我们的方法备份调用堆栈

RecCalc(0) == 0
RecCalc(1) == RecCalc(0) + 2*1 -1 == (0) + 2*1 -1 == 1
RecCalc(2) == RecCalc(1) + 2*2 -1 == (1) + 2*2 -1 == 4
RecCalc(3) == RecCalc(2) + 2*3 -1 == (4) + 2*3 -1 == 9
这并不能解释数学,但可以解释递归

让我们看看数学。 正如@code学徒所解释的,x²=(x-1)²+2x-1 整个递归方案的真正诀窍是(x-1)²

我们知道,对于x=4,我们可以使用(x-1)²加上一些其他垃圾来得到答案。
但那只是3的平方加上一些其他的垃圾

现在,为了得到3的平方,我们知道3²=(x-1)²加上垃圾。
但那只是2的平方加上一些其他垃圾

所以,我们一直向下,直到得到一个简单的答案,返回0。(事实上,对于x=1,也可以返回1)


我希望这能解释它

如果你写一份打印声明,也许会有所帮助

public static void main(String[] args) {
    System.out.println(RecCalc(5));
}
    
public static int RecCalc(int x) {
    if (x == 0) {
        return 0;
    } else {
        int v = RecCalc(x - 1) + 2 * x - 1;
        System.out.println((x-1) + " " + (2*x) + " " + (-1));
        return v;
    }
}
印刷品

0 2 -1
1 4 -1
2 6 -1
3 8 -1
4 10 -1
25

请注意,每行最后两列之和的值为奇数。从1开始的任意数量的连续奇数之和是一个完美的平方。所以本质上,这个方法只是对第一个
x
奇数求和。

试着用不同的
x
值进行逐步处理:先是0,然后是1,然后是2等等。如果你承认
RecCalc
应该返回其输入的平方,你会看到这行返回
(x-1)²+2x-1
,对吗?@njzk2好,但我没有(x-1)^2在递归调用中,但是我有x-1,根据定义,
RecCalc(n)==n²
,对于n的任何值,包括
x-1
?如果是这样的话,那么肯定
RecCalc(x-1)+2*x-1==(x-1)²+2*x-1
您所在地区以外的人很可能不熟悉foil助记符,我对这个公式很熟悉,但我不明白,即使方法的调用是x-1而不是(x-1),程序怎么可能返回x的平方^2递归调用如何返回(x-1)^2?既然
RecCalc(x)
计算
x^2
那么
RecCalc(x-1)
计算
(x-1)^2
。我不知道如何更好地解释它。
return
中的公式相当于我在这里的答案中的代数所给出的
x^2
。@njzk2这就是为什么我提到一般分配属性,因为FOIL只是它的一个neumonic。事实上,即使在我的特定区域,每个人都可能不知道“箔”。我的邻居在上高中,她刚被教过如何把它看作是一种分配属性,而不是一种中性属性。