简体   繁体   English

在此示例中,如何将递归转换为尾递归?

[英]How to convert recursion to tail recursion in this example?

I have this recursive function to add the cubes of n even numbers and I want't to turn it to a tail recursion. 我有这个递归函数来添加n个偶数的多维数据集,而我不想将其转换为尾递归。

int sum_even_cubes_rec(int n) {
if (n < 2) 
    return 0;
if ((n % 2) == 0) {
    return (n*n*n + sum_even_cubes_rec(n - 1)); 
} else {
    return (0 + sum_even_cubes_rec(n - 1));
}
}

This is what I wrote but it is wrong and I don't know how to fix it. 这是我写的,但这是错误的,我不知道如何解决。 Can you please help me. 你能帮我么。

int sum_even_cubes_rec2(int n, int acc) {
if ((n % 2) == 0) {
    return sum_even_cubes_rec2 (n-1, acc + n*n*n); 
} return acc;
}

int sum_even_cubes_helperFunktion(int n) {
return sum_even_cubes_rec2(n, 0);
}

Your approach is correct. 您的方法是正确的。 You have already added acc argument, so that's what you need to return for the base case. 您已经添加了acc参数,因此这是返回基本情况的条件。

The rest of your code is almost right - you need to adjust what you add to acc for the next invocation: 您其余的代码几乎是正确的-您需要为下一次调用调整添加到acc的内容:

int sum_even_cubes_rec2(int n, int acc) {
    if (n < 2) {
        return acc;
    }
    int nextAcc = (n % 2) == 0 ? acc + n*n*n : acc;
    return sum_even_cubes_rec2 (n-1, nextAcc); 
}

Simply it can be written as this 简单地可以这样写

int sum_even_cubes_rec2(int n) {
       static int ans = 0;
       if(n<2){
         int tmp =ans;
         ans =0;
         return tmp;
       }
       ans += ( (n%2==0)? n*n*n : 0 );
       return sum_even_cubes_rec2(n-1);
}
int sum_even_cubes(int n) {
    int ret =0;

    if (n < 2) return 0;

    ret = (n % 2) ? 0: n*n*n;
    return ret + sum_even_cubes(n-1); 
}

Gcc -O2 -S will compile this into (function argument is %edi ; return value is in %eax ; target for recursion-loop is .L4 ) : Gcc -O2 -S将其编译为(函数参数为%edi ;返回值以%eax ;递归循环的目标为.L4 ):

sum_even_cubes:
.LFB0:
        .cfi_startproc
        xorl    %eax, %eax
        cmpl    $1, %edi
        jle     .L5
        .p2align 4,,10
        .p2align 3
.L4:
        xorl    %edx, %edx
        testb   $1, %dil
        jne     .L3
        movl    %edi, %edx
        imull   %edi, %edx
        imull   %edi, %edx
.L3:
        subl    $1, %edi
        addl    %edx, %eax
        cmpl    $1, %edi
        jne     .L4
        rep ret
.L5:
        rep ret
        .cfi_endproc
.LFE0:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM