【问题标题】:Implementation of a double factorial tail-recursive function in C在 C 中实现双阶乘尾递归函数
【发布时间】:2023-03-25 09:27:01
【问题描述】:

我试图在我的 C 代码中实现以下公式时遇到了困难:

不!! = N!/(N-1)!!

代码应该是一个尾递归函数,虽然它确实有效并且计算是正确的,但我很确定这不是一个尾函数 + 我真的不知道返回期间发生了什么阶段。

我当前的代码:

long long int Factorial(int n)    
{    
    if (n < 0)    
        return 0;

    if (n == 0 || n == 1)    
        return 1;

    return (n*Factorial(n - 1));    
}

int DoubleFactorialTail(int n, int fact)    
{
    if (n < 0)
    {
        return 0;
    }
    if (n == 0 || n == 1)
    {
        return fact;
    }
    else
    {
        long long int factorial = Factorial(n);
        return (factorial / DoubleFactorialTail(n - 1, fact));
    }
}

我知道双阶乘尾递归函数应该在最后调用递归函数,但这里我所做的是将它除以值(在这种情况下是递归的),这就是为什么我不是所以确定我的实现是正确的。

编辑:

我最初尝试实现以下内容:

long long int DoubleFactorialTail(int n, int fact)

{
    if (n < 0)
    {
        return 1;
    }
    if (n == 0 || n == 1)
    {
        return fact;
    }
    else
    {
        return (DoubleFactorialTail(n - 2, fact*n));
    }
}

结果将是:

res = (Factorial(n)/DoubleFactorialTail(n-1, 1));

问题是,我们被告知对于 n

【问题讨论】:

  • 您的递归调用都不是尾递归的。首先考虑阶乘,不需要递归定义
  • 这是一个练习吗?我不会以这种方式或递归方式计算双阶乘。
  • 是的,第一个不是尾递归函数,只有第二个应该是尾。
  • 这只是一个练习,我肯定也会以其他方式完成它????
  • 先写成循环,再转成递归。然后应该更容易理解

标签: c recursion factorial tail


【解决方案1】:

我知道双阶乘尾递归函数应该在最后调用递归函数,没有别的

这是真的,所以

return (n*Factorial(n - 1));

return (factorial / DoubleFactorialTail(n - 1, fact));

不会工作。

模式必须是字面意思

return CallToRecursive(args);

原因是尾递归优化让CallToRecursive(args); 返回到此函数的调用者,并且不会向调用堆栈添加帧。

如果添加需要进一步处理返回值的代码,那么它需要在调用堆栈中的一个框架来保存返回值和返回点,这不是 TCO。

解决此问题的方法通常是将正在进行的工作传递给下一次调用。

long long int FactorialTCO(int n, long long factSoFar)
{
    if (n < 0)
        return 0;

    if (n == 0 || n == 1)
        return factSoFar;

    return FactorialTCO(n - 1, n * factSoFar);
}

long long int Factorial(int n) {
     return FactorialTCO(n, 1);
}

注意这一行:

return FactorialTCO(n - 1, n * factSoFar);

准确返回从递归调用返回的内容。这意味着编译器不需要创建新的堆栈帧,并且该调用将返回给该函数的调用者。当我们多次这样做时,我们可以在完成后有效地一直跳回到第一个调用者,而不是展开堆栈帧。

我将替身的转变留给你或其他人。

【讨论】:

    猜你喜欢
    • 2021-01-25
    • 2021-03-18
    • 2018-06-08
    • 1970-01-01
    • 2015-01-08
    • 2019-08-06
    • 1970-01-01
    • 2023-03-20
    • 2018-10-16
    相关资源
    最近更新 更多