自定义递归函数 |不返回任何值|在C中



我想做这个 An=8(An-1)*(An-1)/An-2,而 a1=1,a0=1
使用以下代码 n=2 a2=0.0000 这是完全错误的
另一方面(An之和)S(n)=1+1+0.0000(假数)理论上是正确的

#include <stdio.h>
float rec(int n);
float sum(int n);
main()
{
    int n;
    printf("nInput N of term an: ");
    scanf("%d",&n);
printf("nna%d=%f",n,rec(n));
printf("nnS(%d)=%f",n,sum(n));
}
float rec(int n)
{
    int i;
    float a[1000]={1,1};//a0=1,a1=1
    if(n<0)
        printf("nNegative values of N are invalid");
    else if(n==0)
        return a[0];
    else if(n==1)
        return a[1];
    else if(n>1)
        for(i=2;i<=n;i++)
            a[i]=((8 * a[i-1]*a[i-1]) - 1)/a[i-2];
    return a[i];
}
float sum(int n)
{
    int i;
    float sum=0;
    for(i=0;i<=n;i++)
        sum+=rec(i);
    return sum;
}
float a[1000]={1,1};

初始化a[0] = 1a[1] = 1其余元素以0

现在,您将从函数中返回a[i]。对于n=2它将返回 a[3] ,这当然是0,但不是您所期望的a[2]

现在只需将返回值更改为 a[i-1] 它就会起作用。

float rec(int n)
{
    int i;
    ...
    ...
    return a[i-1];
}
for(i=2;i<=n;i++)
        a[i]=((8 * a[i-1]*a[i-1]) - 1)/a[i-2];
return a[i];

这里的问题,你总是会得到零!!为什么?

假设我输入 3,,现在说 i = 3,alls well a[3] 被计算,现在你的程序回到 for 循环,现在 i =4,它现在不符合检查 i<=n,所以现在我是 4,

您返回的是一个[i],它实际上是[我的答案+1]...

通过返回 a[I-1] 来修复它

rec的这一点上:

return a[i];

i是 3,而不是 2,因为它在循环的最后一次测试之前递增。 因此,您将在最后一个集合之后返回数组的元素。 如果通过返回 a[i-1] 来解决此问题,请小心,因为如果 i 从未初始化或为 0,这将导致问题。 您应该稍微清理一下rec方法来处理这些极端情况,但直接的问题是i是 3,而不是 2。

替换

return a[i];

return a[n];

(顺便说一句,您不需要 0 和 1 的额外分支。

画家

施莱米尔算法的一个很好的例子:)

  • 大约一半的计算不必要地多次完成
  • 数组是不必要的,并且违背了使用递归方法的全部意义

此外,它被定义为容纳 1000 个值,但函数增长得如此之快,以至于在 10 项左右后它将超过浮点容量。

这里有一个更精简的版本:

#include <stdio.h>
float A (int n, float * sum)
{
    if (n <= 0) { *sum = 0; return 0; }
    if (n == 1) { *sum = 1; return 1; }
    if (n == 2) { *sum = 2; return 1; }
    float anm2 = A(n-2, sum); // store A(n-2). sum will be overwritten by A(n-1)
    float anm1 = A(n-1, sum); // store A(n-1) once to avoid calling A twice, and get preceding sum
    float an = ((8 * anm1*anm1) - 1)/anm2;
    *sum += an;
printf ("index %d : term %g sum %gn", n, an, *sum);
    return an;
}
int main (void)
{
    int n;
    float sum;
    printf("nInput N of term an: ");
    scanf("%d",&n); printf("n");
    printf("na%d=%f",n,A(n, &sum));
    printf("nnS(%d)=%f",n,sum);
}

此外,递归是不必要的,会导致代码效率低下和混乱。

在此处查看更直接的解决方案:

#include <stdio.h>
typedef struct {
    float term;
    float sum;
} A; // current term and sum of series A
void compute_A (int n, A * res)
{
    int i;
    float anm1, // a[n-1]
          anm2; // a[n-2]
    // special case for n<=1
    if (n == 1)
    {
        res->sum = res->term = 1;
        return;
    }
    if (n <= 0)
    {
        res->sum = res->term = 0;
        return;
    }
    // initial terms
    anm2 = anm1 = 1;
    // initial sum
    float sum = anm1+anm2;
    // compute the remaining n-2 terms and cumulate the sum
    for (i = 2 ; i <= n ; i++)
    {
        // curent term
        float an = ((8 * anm1*anm1) - 1)/anm2;
        // cumulate sum
        sum += an;
        // shift computation window
        anm2 = anm1;
        anm1 = an;
printf ("index %d : term %g sum %gn", i, an, sum);
    }
    // report result
    res->sum  = sum;
    res->term = anm1;
}
int main (void)
{
    int n;
    A res;
    printf("nInput N of term an: ");
    scanf("%d",&n); printf("n");
    compute_A (n, &res);
    printf("na%d=%f",n,res.term);
    printf("nnS(%d)=%f",n,res.sum);
}
float rec(int n){
    static max_i = 1;
    static float a[1000]={1,1};//a0=1,a1=1
    int i;
    if(n<0){
        printf("nNegative values of N are invalid");
        return NAN;//<math.h>
    }
    if(n >= 1000){
        printf("nMore than 1000 are invalid");
        return NAN;
    }
    if(n<2)
        return a[n];
    if(n>max_i){
        for(i=max_i+1;i<=n;++i)
            a[i]=((8 * a[i-1]*a[i-1]) - 1)/a[i-2];
        max_i = n;
        return a[n];
    }
    return a[n];
}

最新更新