【问题标题】:C recursive functionC递归函数
【发布时间】:2012-04-15 10:05:38
【问题描述】:

我有这个代码:

#include <stdio.h>
#include <stdlib.h>


int func(int n0, int n);

int main ()
{
    int n0, n, nFinal=0;
    printf ("Enter constant (n0): ");
    scanf ("%d", &n0);
    printf ("Enter the number of iteractions (n): ");
    scanf ("%d", &n);
    nFinal = func(n0, n);
    printf ("nFinal after %d iteractions is %d: \n", n, nFinal);
    return 0;
}

int func(int n0, int n){
    int i,nFinal=0;

    for (i = 0; i < n; i++){
        nFinal = (nFinal*nFinal) + n0;
    }

    return nFinal;
}

nFinal 在 for 循环中计算。我想实现相同的结果,但使用递归函数。

据我所见,我无法更改函数调用,因为我总是需要起始编号和迭代次数。因此,在第一次迭代之后,程序将不得不再次调用nFinal = func (n0, n);,但由于我需要在每次迭代 nFinal 的计算值时,我必须更改它。

是否可以创建一个递归函数但将函数保持为nFinal = func (n0, n);

有人可以指点我吗?

【问题讨论】:

  • 在函数体func 中,您在初始化之前使用了nFinal。这是正确的吗?
  • @Chris 对不起。 nFinal 初始化为零

标签: c function recursion


【解决方案1】:

看看你的功能

int func(int n0, int n){
    int i,nFinal=0;

    for (i = 0; i < n; i++){
        nFinal = (nFinal*nFinal) + n0;
    }

    return nFinal;
}

如果n是(小于)0,你的结果就是0。那么nFinal的新值就是nFinal^2+n0的旧值,所以你得到:

int func(int n0, int n){
    if (n <= 0) return 0;

    int f = func(n0, n-1);
    return f*f + n0;
}

【讨论】:

  • 糟糕,我以为我出错并删除了,但它似乎没问题。
  • 谢谢。它正在工作,但我有 1 个疑问。我知道f = func(n0, n-1) 将递归直到 nreturn f*f + n0。此时它不会是0*0+n0?假设我有 n0 = 2 和 n = 4。因为 n 它不是 func(2,4-1); 然后 func(2,3-1); 然后 func(2,2-1); 最后是 func(2,1-1);。由于 n return f*f + n0; 不会执行 0*0+2 并将该值返回给 main 但 f*f 会再次执行递归调用?
  • 我会告诉你你的问题是什么:你正试图思考递归(从上到下)!这真的不是理解递归的方式,试着从下到上弄清楚。 f(n0, 0) 将是 0f(n0, 1) 将是 f(n0, 0)^2 + n0 = 0^2 + n0 等等......
  • 如果你想理解递归,一般来说有一些口头禅:我告诉你第一个:1.“不要递归地考虑它”,2.“假设你已经有了n的答案-1 - 并考虑如何得出 n" 的答案,3. 直接回答小值的问题(以确保递归将结束)
  • 谢谢。我的理解有点模糊,但会尝试弄清楚。
【解决方案2】:

我想你正在寻找这个:

int func(int n0, int n){
    if (n > 1){
        int nFinal = func(n0, --n);
        return (nFinal*nFinal) + n0;
    }
    return n0; // (0*0) + n0
}

注意if (n == 1)它返回n0,否则它调用func,将其返回值存储在nFinal中并返回(nFinal*nFinal) + n0

此函数的等效版本也可以为n == 1return 0n == 0 调用自身。

【讨论】:

  • 感谢您的解决方案。它与 Anthales 提供的页面在同一页面上。我的疑问与解决方案中的相同。
【解决方案3】:

在每次迭代中,您对原始值(和参数)进行一些数学运算,然后将其存储。关于如何使其递归,您有两种广泛的选择。

  1. 首先对n-1 进行所有迭代,然后在返回之前对其进行更多数学运算。这似乎更自然地首先使它成为递归。

  2. 首先执行此迭代的数学运算,然后将结果传递给递归调用以执行其余的计算。这是尾递归(这不太重要,除非n 会变得非常大并且您知道您的编译器会对其进行优化以节省堆栈空间;-)。

递归就像数学归纳法。你需要考虑你的基本情况和你的归纳步骤。在您的函数中,您的基本情况类似于:

  • 如果n = 0,则func(n0, n) 返回0

你的步骤是:

  • func(n0, n) 返回func(n0,n-1) * func(n0,n-1) + n0。 (您可以只调用一次函数并将其保存到局部变量中。)

这转换为标准的 if-else 构造。看看你到目前为止是否能理解,如果你卡住了,请告诉我。

【讨论】:

    【解决方案4】:
    #include <stdio.h>
    #include <stdlib.h>
    
    int func_r(int n0, int n, int acc);
    
    int main (){
        int n0, n, nFinal;
        printf ("Enter constant (n0): ");
        scanf ("%d", &n0);
        printf ("Enter the number of iteractions (n): ");
        scanf ("%d", &n);
        nFinal = func_r(n0, n, 0);
        printf ("nFinal after %d iteractions is %d: \n", n, nFinal);
        return 0;
    }
    
    int func_r(int n0, int n, int acc){
        if(n == 0)
            return acc;
        return func_r(n0, n-1, acc*acc + n0);
    }
    

    【讨论】:

    • 理想情况下,我应该保持 int func(int n0, int n) 原样。不过感谢另一个解决方案
    猜你喜欢
    • 1970-01-01
    • 2016-02-13
    • 2021-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多