根据维基catalan definition from wiki,我看到下面的表达式:
我能理解前两个表达式,但对第三个表达式真的很困惑。 pi符号代表乘法。表达式是否代表下面的代码:
for (int i = 2; i < n + 1; i++) {
sum *= (n + i)/i;
}
我的代码在
下面public class Test {
public int getCatalan(int n) {
//Catalan Number = (2n)!/(n+1)!*n!
int product = 1;
if (n == 1)
return 1;
for (int i = 2; i < n + 1; i++) {
product *= (n+i)/i;
}
return product;
}
public static void main(String[] args) {
Test test = new Test();
for (int i = 1;i < 7; i++) {
System.out.println("when i=" + i + " its catalan number is "+ test.getCatalan(i));
}
}
}
我得到的结果完全错误
有人帮助我吗?
答案 0 :(得分:2)
是。这大致意味着什么(假设您将sum
初始化为1)。
但要注意整数除法。如果你写(n + i)/i
并且n
和i
都是整数,你可能会发现自己在某些语言中有一些意想不到的输出。
例如,在Java中,如果n = 3
和i = 2
,(n + i)/i = 2
,而不是2.5
,则int / int = int
,我们无法存储{{ 1}}在一个整数。
如果你在某处投了2.5
或添加double
或+ 0.0
,结果将是* 1.0
(double
)并且应该是正确的
另请注意,double / int = double
本身应为sum
/ double
,而不是float
(因为,int
无法存储{{ 1}},类似于上面提到的)。如果您希望输出为sum
,则应2.5
。
int
(我也将Math.round
更改为int n = 3;
double product = 1;
for (int i = 2; i <= n; i++) {
product *= (0.0 + n + i)/i;
}
System.out.println(product); // 5
- 后者对我来说更清楚,但它在功能上没有改变代码)
有关更多技术细节,请参阅JLS - Division Operator /和Binary Numeric Promotion。
答案 1 :(得分:1)
是。确保将sum
(可能应称为product
)初始化为1。
答案 2 :(得分:0)
使用long或BigIntegers(或使用您使用的任何语言的等效物)来避免浮点错误可能更安全。您可以跟踪分子和分母并在末尾划分。 (或在步骤之间保持减少以减少溢出的可能性)
long catalan(long n) {
long p = 1;
long q = 1;
for (long k = 2; k <= n; k++) {
p *= (n + k);
q *= k;
// these 3 lines are optional, and just delay when overflow happens
long gcd = gcd(p, q);
p /= gcd;
q /= gcd;
}
return p / q;
}
在这里查看一个比较:https://coderpad.io/565957使用双打将在n = 30时给你错误的答案,gcd我的只有33到好,但是你可以轻松换掉BigIntegers的长号无限期地去。