计算lg(N!):任何人都有更好的递归方法?

时间:2011-08-08 05:01:44

标签: c++ recursion factorial logarithm

我认为这篇文章的标题解决了我的问题。但重申一下,我想知道是否有人有更好的方法解决这个问题。

/* Write a recursive program to compute lg( N! ) */

#include <iostream>

#include <cmath>

using namespace std;

long double log_base2( long double N ) {
    return log( N )/log( 2.0 );
}

long double lg_n_factorial( long N ) {
    if( 1 == N ) return log_base2( static_cast<long double>( N ) );
    else return lg_n_factorial( N -1 ) + log_base2( static_cast<long double>( N ) );
}

int main( int argc, char *argv[] ) {
    cout << ( lg_n_factorial( 10 ) ) << endl;
    return 0;
}

根据人们的回答,我应该澄清一下,这是书中的一个问题,而且书中说这是一个递归的做法。我正在练习编程问题,并试图从别人那里获得反馈,这样我就可以在成为更好的程序员时抓住我的错误。

3 个答案:

答案 0 :(得分:3)

为什么使用递归?迭代解决方案同样适用:

long double lg_n_factorial( long N ) {
    long double result = 0;
    while (N > 1) {
        result += log_base2(static_cast<long double>(N));
        N--;
    } 
    return result;
}

这样,您可以处理的最大值仅受LONG_MAX的值约束,而不是在堆栈溢出之前发生适合堆栈的递归调用次数。

答案 1 :(得分:2)

只是迭代地做?我没有看到这个问题需要递归解决的原因。如果你有一个要求(由于某种原因或其他原因)以递归方式执行它,你的方式似乎工作正常,虽然你的基本情况可以只返回0(任何基数中的log(1)为0)。

此外,无需在每个步骤转换为基数2:最后可以执行一次。

答案 2 :(得分:0)

我会说你有正确的基本想法。从风格的角度来看 在视图中,如果您有一次返回,代码将更具可读性 声明,并使用?:,但对于这样的短程序,差异是 可以忽略不计,不值得担心。更多的个人品味, 我把递归放在最后,非常清楚它是什么 尾递归。 (并且编译器检测尾递归应该能够 重新排序算术并找到它,但人类读者看得更清楚 如果递归是最后一件事。)