语句执行的递归和顺序

时间:2014-06-26 00:23:10

标签: ruby memory-management recursion trace

这个问题涉及如何执行语句和涉及递归的语句,以及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
  1. 在原始的append方法(代码的顶部)中,为什么ruby在第一次递归调用时停止计算,继续执行第3行,然后执行第二次递归调用,然后连接两次递归的输出? / LI>
  2. 如果第2行和第3行是递归的唯一部分,则输出将是[0,2,4,6],按升序排列。 Ruby在执行中使用的约定是什么?为什么此代码未提供输出[6,4,2,0],因为在n-1之前调用了array << n*2
  3. 是否有关于如何处理这些递归调用的正确定义或编程理论?

1 个答案:

答案 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,然后是24,最后是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;
}