【发布时间】:2011-12-09 15:11:30
【问题描述】:
这个功能有问题?
unsigned long factorial(unsigned long m)
{
return (m == 0) ? 1 : m * factorial(m - 1);
}
如果我添加另一个功能:
int myCombina(int q, int p)
{
return factorial(q) / ( factorial(q) * factorial(q-p) );
}
此 myCombina() 效率不高,因为应在其中取消最大公约数以查找组合。
max(factorial(q), factorial(q-p)) 可以取消。 我们只需要计算 q x (q-1) ... x (q -k +1)。
还有其他问题吗?
欢迎任何 cmets。
谢谢
【问题讨论】:
-
在任何不支持尾调用优化的语言中,阶乘的递归实现也将是极其低效的。迭代解决方案将仅使用 O(1) 临时存储,并且通常会运行得更快。
-
明显的语言是 C/C++,所以支持尾调用优化。 stackoverflow.com/questions/34125/…
-
@DanielPryden:实际上,如果你使用 bignum 类型,它的存储量是 O(log m)。
-
@gkuan:“支持”与“保证”不同。没有任何自尊的 C 或 C++ 编程会依赖于生产代码中的无限递归(除非深度为 O(log n))。
-
@DanielPryden tail-call optimization 既是一种语言特性,也是一种代码特性,在这种特殊情况下,它不能被应用(如果你返回
m*factorial(m-1)调用必须在乘法完成之前返回,这意味着递归不能转换为循环。现在,如果它被转换为允许优化(传递一个带有临时结果的额外参数),那么编译器可以执行优化.
标签: c++ c recursion stack stack-overflow