这个问题涉及如何执行语句和涉及递归的语句,以及Ruby将以什么顺序处理。具体来说,正如我在网上学习的那样,我发现Ruby并没有遵循堆叠形式的内存管理中的Last in first out约定,而是拥有垃圾收集器。在所有代码之后,我在底部编号问题。我希望我已经说清楚了一切,但请让我知道问题的哪些部分可能需要改进。谢谢。
def append(array, n)
return array if n < 0 #base case, how we end this thing
array << n*2 #Line No. 1
append(array, n - 1) #Line No. 2
array << n*2 #Line No. 3
end
append( [], 3)
#output [6,4,2,0,0,2,4,6]
下面两行给出[6,4,2,0]
array << n*2 #Line No. 1
append(array, n - 1) #Line No. 2
当两个语句的顺序颠倒时,输出为[0,2,4,6]
append(array, n - 1) #Line No. 2
array << n*2 #Line No. 3
[0,2,4,6]
,按升序排列。 Ruby在执行中使用的约定是什么?为什么此代码未提供输出[6,4,2,0]
,因为在n-1
之前调用了array << n*2
?答案 0 :(得分:1)
Ruby在这里没有什么不寻常之处,只不过是任何其他“典型”的计算机语言。
在原始的append方法(代码的顶部)中,为什么ruby在第一次递归调用时停止计算,继续执行第3行,然后执行第二次递归调用,然后连接两次递归的输出? / p>
我没有看到任何证据。输出6,4,2,0
的前半部分来自第1行。后半部分0,2,4,6
来自第3行。请注意,它第一次落到第3行时是n==0
。因此,6,4,2,0
之后的下一个值是0
,然后是2
,4
,最后是6
。它就像任何其他计算机语言一样弹出调用堆栈LIFO。
如果第2行和第3行是递归的唯一部分,则输出将是[0,2,4,6],按升序排列。 Ruby在执行中使用的约定是什么?为什么这段代码没有给出输出[6,4,2,0],因为n-1是在数组&lt;&lt;&lt;&lt; N * 2?
因为它必须在返回到第3行之前调用append
4次。到这时,n=0
这就是0
在这种情况下仍然是第一位的原因。< / p>
是否有关于如何处理这些递归调用的正确定义或编程理论?
这只是LIFO。再考虑一下。
如果你仍然不相信,这里是C ++代码打印完全相同的序列:
#include <iostream>
#include <list>
using namespace std;
list<int>& append( list<int> &array, int n )
{
if( n < 0 ) return array;
array.push_back(n*2);
append( array, n-1 );
array.push_back(n*2);
return array;
}
int main()
{
list<int> array;
append( array, 3 );
for( int& x : array ) cout << x << ' ';
cout << endl;
}