我想为加泰罗尼亚数字编写代码.Catalan数字定义如下:
C(n) = 2n C n/(n+1)
。但是我没有计算(2n C n)
,而是想利用以下事实自下而上计算加泰罗尼亚数字:
Catalan(n) =
2n! /n! * n! * (n+1)
Catalan(n+1) =
2*(n+1)
--------------------------- =
(n+1)! * (n+1)! * ((n+1)+1)
(2n+2) * (2n+1) * 2n!
------------------------------- =
(n+1) * n! * (n+1) * n! * (n+2)
(2n+2) * (2n+1) * 2n!
----------------------------------- =
(n+1) * (n+2) * n! * n! * (n+1)
(2n+2) * (2n+1)
--------------- * Catalan(n)
(n+1) * (n+2)
现在利用上述事实,这是我的以下代码:
int catalan(int n)
{
if (n == 1)
return 1 //since c(1)=1 is my base case
else
return (((2*n+2) * (2*n+1))/((n+1)*(n+2))) * catalan(n-1)
}
现在,我的问题是为什么当我的输入为4时,上面的函数返回12。它应该返回14,因为c(4)= 14。
有人可以帮助我吗?
答案 0 :(得分:9)
即使C(n)
的原始表达式可能错误,实际的重复发生
正确。
您可以进一步将其简化为
但就C(n+1)
而言,这为您提供了C(n)
。根据{{1}},您想要的是C(n)
。插入C(n-1)
以获取
另请注意,为了防止整数除法截断结果,您需要先乘以然后除以。
n-1
编辑:如果的值需要经常使用而不只是计算一次,那么使用memoization可能是个好主意,以避免计算它们不止一次。
此外,请注意,由于增长率很高,加泰罗尼亚语数字会快速溢出任何预定义的int catalan(int n) {
if (n == 1)
return 1;
else
return 2 * (2*n - 1) * catalan(n-1) / (n+1);
}
整数数据类型。
答案 1 :(得分:4)
根据http://en.wikipedia.org/wiki/Catalan_number,递推公式为:
C(n+1)=2(2n+1)/(n+1) * C(n)
或C(n)=2(2(n-1)+1)/n * C(n-1)
我想你已经忘记了从C(n+1)
到C(n)
的转变。
答案 2 :(得分:3)
当你从数学表达式转到代码时,你隐含地在加泰罗尼亚语()部分中用n-1替换n,而不是在表达式本身中。因此,您计算值N的乘数并将其乘以C(N-1)。尝试在你的等式中用N-1代替N,这导致:
int catalan(int n)
{
if (n == 1)
return 1 //since c(1)=1 is my base case
else
return (((2*n) * (2*n-1))/((n)*(n+1))) * catalan(n-1)
}
答案 3 :(得分:3)
您的公式中存在错误。你的公式用于计算c(n + 1),但你的输入是n。这可以通过在计算中使用它之前将n的值减1来解决:
int catalan(int n)
{
if (n == 1)
return 1 //since c(1)=1 is my base case
else
n=n-1
return (((2*n+2) * (2*n+1))/((n+1)*(n+2))) * catalan(n)
}
编辑:正如abeln所指出的,上面的代码会因整数除法而丢失余数而失败。请改用以下代码:
int catalan(int n)
{
if (n == 1)
return 1 //since c(1)=1 is my base case
else
n=n-1
return ((catalan(n) * (2*n+2) * (2*n+1))/((n+1)*(n+2)))
}
答案 4 :(得分:0)
在你的公式中,你有
(2n)!
C(n) = ----------------
(n+1)! * n! * n!
实际上加泰罗尼亚数字被定义为
(2n)!
C(n) = ----------------
(n+1)! * n!
即。你在分母上有一个因子太多了