【问题标题】:Iterative or Recursive Factorial [closed]迭代或递归阶乘[关闭]
【发布时间】:2015-01-28 11:54:20
【问题描述】:

我以这种方式递归地实现了阶乘:

int factorial(int x){
    if (x <= 0)
        return 1;
    else
        return (x*factorial(x - 1));
}

int _tmain(int argc, _TCHAR* argv[])
{
    std::cout << "Please enter your number :::";
    int x;
    std::cin >> x;
    std::cout<<"factorial(" << x << ") = "<< factorial(x);
    getchar(); getchar();
}

哪种实现此类代码的方式更有用,是使用迭代和循环编写它还是像上面那样递归编写它?

【问题讨论】:

  • 这完全取决于你对“有用”的定义。
  • 计算阶乘几乎没有用处。
  • 一般来说,如果你可以不使用递归并使用迭代算法,你应该这样做。没有这么简单的东西,但调试递归算法可能会很痛苦。有趣的问题是内存会发生什么,尤其是堆栈,例如,想想如果你用参数 30 调用你的函数会发生什么。PS 不要太大,阶乘很快就会超过 maxint。
  • 因为适合 int 的阶乘范围很小。我会简单地使用所有预先计算的值的数组。
  • 有什么用?这两种方法对于教授初学者递归和迭代编程都很有用。

标签: c++ algorithm recursion iteration


【解决方案1】:

这取决于数字本身。

对于正常范围的数字,可以使用递归解决方案。由于它利用以前的值来计算未来的值,它可以提供'factorial(n-1)'的值即时。

factorial(n) = factorial(n-1) * n

但是,由于递归使用堆栈,如果您的计算深度超过堆栈大小,它最终会溢出。此外,递归解决方案会因为每次递归调用的病态级别的寄存器的大量推送而导致性能不佳

在这种情况下,迭代方法是安全的。

看看this的比较。

希望对你有帮助!

【讨论】:

  • 不知道你是怎么想出更快的。这种优化同样适用于迭代的、较小的循环,而不是较少的递归调用。
  • 同意@TonyHopkinson ,我已经进行了编辑。谢谢
  • 知道了!谢谢。
【解决方案2】:

在 C++ 中,递归实现通常比迭代实现更昂贵。 原因是每次调用都会创建一个新的堆栈帧,其中包含需要保存的返回地址、局部变量和寄存器等数据。因此,递归实现需要的内存量与嵌套调用的深度成线性关系,而迭代实现使用恒定的内存量。 在您的特定情况下,即尾递归,编译器优化可能会使用直接跳转来切换函数调用,以防止不必要地使用调用堆栈上的内存。 有关更详细的说明,您可能需要阅读: Is recursion ever faster than looping?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-17
    • 1970-01-01
    • 2012-06-25
    • 2015-05-20
    • 1970-01-01
    • 2015-04-20
    • 2016-01-28
    • 1970-01-01
    相关资源
    最近更新 更多