我认为这篇文章的标题解决了我的问题。但重申一下,我想知道是否有人有更好的方法解决这个问题。
/* 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;
}
根据人们的回答,我应该澄清一下,这是书中的一个问题,而且书中说这是一个递归的做法。我正在练习编程问题,并试图从别人那里获得反馈,这样我就可以在成为更好的程序员时抓住我的错误。
答案 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)
我会说你有正确的基本想法。从风格的角度来看
在视图中,如果您有一次返回,代码将更具可读性
声明,并使用?:
,但对于这样的短程序,差异是
可以忽略不计,不值得担心。更多的个人品味,
我把递归放在最后,非常清楚它是什么
尾递归。 (并且编译器检测尾递归应该能够
重新排序算术并找到它,但人类读者看得更清楚
如果递归是最后一件事。)