输入为{4,7,3,6,7}
,输出为:
[81]
[40, 41]
[21, 19, 22]
[11, 10, 9, 13]
[4, 7, 3, 6, 7]
我有的递归程序如下所示,我已经添加了一些print语句来理解递归:
import java.util.Arrays;
public class triangle_array {
public static void print(int a[])
{
if(a.length==0)
return;
int n=a.length;
int newa[]=new int[n-1];
for(int i=0;i<n-1;i++)
{
newa[i]=a[i]+a[i+1];
}
System.out.println("here1") ;
print(newa);
System.out.println("here2") ;
if(newa.length!=0)
System.out.println(Arrays.toString(newa));
}
public static void main(String args[])
{
int a[]={4,7,3,6,7};
print(a);
System.out.println(Arrays.toString(a));
}
}
我的输出为:
here1
here1
here1
here1
here1
here2
here2
[81]
here2
[40, 41]
here2
[21, 19, 22]
here2
[11, 10, 9, 13]
[4, 7, 3, 6, 7]
我无法完全理解这种递归,
从上面的here
语句中,我理解打印方法首先被递归调用,当条件失败时,它返回到打印之外并转到该行并打印“here2”2次并验证newa的长度为零,直到我理解为止,但在下一次迭代中,对于println语句,newa的长度如何增加以及下面的条件如何变为true?
答案 0 :(得分:1)
通常,如果在递归方法中有打印,则递归调用之前的所有打印将按递增深度增加的顺序打印,递归调用之后的所有打印将打印在递归调用中。逆序。
public static void demoRecursion( int n, int depth ) {
if ( n <= 0 ) {
return;
}
System.out.println( "Before recursive call, depth " + depth );
demoRecursion( n - 1, depth + 1 );
System.out.println( "After recursive call, depth " + depth );
}
如果您使用demoRecursion( 3, 1 )
调用此方法,则会获得:
Before recursive call, depth 1
Before recursive call, depth 2
Before recursive call, depth 3
After recursive call, depth 3
After recursive call, depth 2
After recursive call, depth 1
因此,a
的大小并没有增加。只是在深度为1时,你有一个5项数组,深度为2,你有一个4项数组,深度为3,你有3个,依此类推。
因此,由于我在上面演示的反向打印效果,每个深度阵列都在之后打印更深层次的数组,这是更短的。
如果您在递归调用之前打印了数组,那么打印将按递减顺序排列。
答案 1 :(得分:1)
你需要认真思考才能正确理解它。
由于你不明白newa
的大小如何减少,我将解释那部分。首先,从print
调用main
方法。
然后,第一个print
开始执行,并创建长度为4的newa
并停在print(newa)
而第二个print
开始
然后,第二个print
开始执行,并创建长度为3的newa
,并在第三个print(newa)
启动时停在print
。
然后,第3个print
开始执行,并创建长度为2的newa
,并在第4个print(newa)
开始执行时停在print
。
然后,第4个print
开始执行,并创建长度为1的newa
,并在print(newa)
开始执行时停在print
。
然后,第5个print
开始执行,并创建长度为0的newa
,并在print(newa)
停止,同时第6个print
开始执行。
然后,第6个print
开始执行,并在return;
处停止,此时长度为0。
第五个print
继续,长度为0时,不会打印任何内容
第4个print
继续并打印newa
(长度为1)
第3个print
继续并打印newa
(长度为2)
第二个print
继续并打印newa
(长度为3)
第一个print
继续并打印newa
(长度为4)
最后,main
打印整个数组。
答案 2 :(得分:0)
newa
的长度不会增加,它总是减少一个。最短的一个首先被打印,因为递归调用是之前打印数组的指令。所以它说“创建新的更短的数组,然后先递归处理它(涉及打印),然后自己打印”。
顺便说一句,这种结构的方式有点奇怪。不是在newa
方法的末尾打印print
,我认为打印a
(没有围绕它的if
更有意义,然后你也不需要使用main
方法打印。
答案 3 :(得分:0)
您的功能以
开头if(a.length==0)
return;
因此,当a
为空时,该函数会明确停止,但在这种情况下,当a
通过给出0长度a
来逐渐减少完成时,它会停止。因此,如果您的原始数组有4个条目,该函数将自行调用3次。 5次入场将拨打4次。等等。并且由于每个调用可能会回想起来,5个条目将调用functin,n给出一个包含4个条目的数组,它将给出3个条目的数组,直到单个条目的数组。
int newa[]=new int[n-1];
for(int i=0;i<n-1;i++)
{
newa[i]=a[i]+a[i+1];
}
这是关键:newa []是小于a
的一维(n-1
,而n
是a
的长度。这就是为什么在每一行上数组大小增加1(最后调用,第一次打印)。这是每次提供较小数组的部分。
for循环只是将a的两个邻居值的总和加上new。
这是它将连续提供的:
[4, 7, 3, 6, 7]
[4+7, 7+3, 3+6, 6+7] --> [11, 10, 9, 13]
[11+10, 10+9, 9+13] --> [21, 19, 22]
[21+19, 19+22] --> [40, 41]
[40+41] --> [81]
首先显示较小的数组,因为当您调用该函数时,它将调用自身直到可能的最小数组。并且打印的结构使得最后一次调用是第一次打印,因为最后调用的函数将是第一个完成,另一个调用不会完成,直到下面的级别还没有完成。这就是为什么你认为a正在增加,你必须以相反的顺序阅读这些功能。
关于您的打印以进行调试。长期的&#34; here1&#34;是由于您在函数打印输出之前打印它的事实。这就是为什么你在这里得到了很多东西1。然后每个函数调用打印输出。
最后,关于最后一个条件:
if(newa.length!=0)
当a为[81]时,newa将是长度为0的数组,以确保您不能打印0长度的数组。所以这种情况总是如此,直到最后一级。
请注意,将print(newa);
置于该条件下并删除检查a
的第一部分并不是一个0长度的数组不会改变函数中的任何内容
答案 4 :(得分:0)
基本上,该方法通过对连续元素求和来重复地使阵列变小。例如:
4, 7, 3, 6, 7
|/ |/ |/ |/
11 10 9 13
|/ |/ |/
21 19 22
|/ |/
40 41
|/
81
它的工作方式是在每次调用时,它创建一个新的数组,它是一个尺寸较小的元素,称为newa,每个元素newa [i]根据公式newa [i] = a [i]计算+ A [1 + 1]。显然我们想停止某个时候,我们不想继续递归并获得StackOverFlowException,所以当输入数组为空时我们停止。所以,在伪代码中,整个事情是
print(a):
if a is empty
escape from function
else
create newa array of length a.length-1
newa[i] = a[i]+a[i+1] //fill the smaller array
print(newa) // print the smaller array
答案 5 :(得分:0)
有什么可以帮助你理解的是删除所有println语句,而只是在print方法的最开始只放一个System.out.println(Arrays.toString(newa))
。三角形将被反转,这将更有意义。