我有验证工作,如果可以通过尾部递归来计算加泰罗尼亚数,我可以使用定义使用堆栈递归来进行计算,但是我不能通过尾部来进行计算递归
int catalan(int n){
if(n==0){
return 1;
}
else{
return 2*(2*n-1)*Catalan(n-1)/(n+1);
}
}
答案 0 :(得分:0)
指定乘数和除数作为函数的参数,
unsigned long catalan_tail(unsigned long n,
unsigned long multiplier,
unsigned long divisor)
{
/* Optional TODO: Divide multiplier and divisor by
their greatest common divisor? */
if (n < 2)
return multiplier / divisor;
else
return catalan_tail(n - 1, multiplier * 2*(2*n - 1), divisor * (n + 1));
}
和包装函数
unsigned long catalan(unsigned long n)
{
return catalan_tail(n, 1, 1);
}
提供额外参数的初始值。基本上,我们通过将中间结果作为额外的参数提供来推迟对返回值进行的计算,以便最深层的迭代可以做到这一点。
我们必须将乘数和除数作为单独的值提供,因为最终迭代只能保证结果为整数。
“可选TODO” 部分本身并不是加泰罗尼亚语数字所特有的,但是在处理阶乘,乘除运算时通常是可取的。 greatest common divisor的二进制方法易于实现且足够快,并且通常有助于将中间值保持在所使用类型的范围内。
找出c = a*b
是否溢出的一种简单方法是检查c/a == b
(假设为a
,a >= 1
)。