【问题标题】:c++ Recursion array explanationc++递归数组解释
【发布时间】:2014-07-06 23:33:48
【问题描述】:

您好,我正在学习递归,目前我有几个技巧问题需要剖析 - 这是递归函数之一

int rec(int niz[], int start, int end){

if (start == end)
{

    return niz[start]; // vraca zadnji
}

int temp = rec(niz, start+1, end);


// control output
cout << "\n-----\n";
cout << "start "  << start << endl;
cout << "niz[start] "  << niz[start] << endl;
cout << "end "  << end << endl;
cout << "temp "  << temp << endl;
cout << "\n-----------------------------------------\n";
//contrl output end

return ((niz[start] < temp) ? niz[start] : temp);
}

我包含了一个 cout 块来控制呼叫中的工作。这是主要部分

    int niz[] = {1,2,3,4,5,6,7}; 
    cout << rec(niz, 0, 3);

这是我的输出:

-----
start 2
niz[start] 3
end 3
temp 4
------------------

----- 
start 1
niz[start] 2
end 3
temp 3
------------------

-----
start 0
niz[start] 1
end 3
temp 2
------------------

1

谁能解释一下 temp 值是如何计算和返回的,以及我如何得到 1 作为这个函数的返回值?

提前谢谢你!

【问题讨论】:

    标签: c++ recursion


    【解决方案1】:

    递归函数是调用自身的函数。

    int temp = rec(niz, start+1, end);
    

    在这里,您在其中调用“rec”函数,但参数已更改(start + 1)。您在彼此内部调用这些函数,直到“开始”等于“结束”(然后它返回)

    if (start == end)
    {
    
        return niz[start]; // vraca zadnji
    }
    

    在最深的一个返回后,第二个最深的继续它的流程,打印一些信息。

    cout << "\n-----\n";
    cout << "start "  << start << endl;
    cout << "niz[start] "  << niz[start] << endl;
    cout << "end "  << end << endl;
    cout << "temp "  << temp << endl;
    cout << "\n-----------------------------------------\n";
    

    然后它返回 niz[start] 和 temp(本地值)之间的最小值。

    return ((niz[start] < temp) ? niz[start] : temp);
    

    然后第三个最深的继续它的流动,依此类推。直到它到达第一个函数。

    在您的主要部分中,您将 end 设置为 3,因此它对前 3 个元素执行操作(它到达第四个元素,但除了返回其值之外不做任何事情)。通过比较作为 start 传递的 niz[0] 和递归函数返回的 temp(恰好是相同的),您得到 1。等于,所以返回值为niz[0],即1;

    当使用递归函数时,你应该有某种“退出点”来防止递归变得无限,即

    if (start == end)
    {   
        return niz[start];
    }
    

    一般来说,递归函数如下所示:

    f()
    {
        //return condition
        //some work
        f();
        //some work
        //return
    }
    

    你可以这样看待它们

    f()
    {
        //some code
        f()
        {
            //some code
            f()
            {
                //some code
                f()
                {
                    ...
                    //eventually the return condition is met
                }
                //some code
                //return
            }
            //some code
            //return
        }
        //some code
        //return
    }
    

    请记住,未处理的递归可能会导致内存泄漏,因为每个函数调用都带有额外的数据。

    f()
    {
        f();
    }
    

    由于系统数据已经创建,会导致栈溢出;

    您可能想观看“盗梦空间”以更好地理解它:)

    【讨论】:

      【解决方案2】:
       rec(niz, 0, 3)                          (D)
        |
        ---->rec(niz, 1, 3)                    (C)
              |
              ----> rec(niz, 2, 3)             (B)
                     |
                     ----> rec(niz, 3, 3)      (A)
      

      你调用 (D) 调用 (C) 来计算 temp 等等直到 (A)。 在 (A) 中 start==end 并返回 niz[3]=4

      在(B)中:

      temp = 4((A)的结果)

      start = 2

      由于4 大于niz[start]=3 (B) 返回3

      在 (C) 中:

      temp = 3((B)的结果)

      start = 1

      由于3 大于niz[start]=2 (B) 返回2

      在(D)中:

      temp = 2((C) 的结果)

      start = 0

      由于2 大于niz[start]=1 (B) 返回1

      【讨论】:

        【解决方案3】:

        您的递归行在您的打印语句块之前。根据递归的性质,它在该递归行上进行函数调用并停止调用者函数的执行,直到被调用者完成为止。因此,您需要在打印当前元素之前处理下一个元素。

        在您的示例中,发生了以下情况:

        Layer 1:
            Is start equal to end? No.
            What is the result of the next element? Don't know yet, recurse.
        Layer 2:
            Is start equal to end? No.
            What is the result of the next element? Don't know yet, recurse.
        Layer 3:
            Is start equal to end? No.
            What is the result of the next element? Don't know yet, recurse.
        Layer 4:
            Is start equal to end? Yes!
            Return the current element, 4.
            End layer 4.
        Layer 3:
            Now know next element, start printing for the 3rd element.
            Return 3.
            End layer 3.
        Layer 2:
            Now know the next element, start printing for the 2nd element.
            Return 2.
            End layer 2.
        Layer 1:
            Now know the next element, start printing for the 1st element.
            Return 1.
            End layer 1.
        End program.
        

        如您所见,数组元素是向后打印的,因为打印语句在递归调用之后。我希望它们按顺序打印,在递归调用之前打印它们,或者创建一个缓冲区并将每个打印部分附加到缓冲区的前面。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-06-01
          • 2022-01-18
          • 1970-01-01
          • 2022-01-11
          • 2016-05-08
          • 1970-01-01
          • 2021-11-04
          • 2014-01-16
          相关资源
          最近更新 更多