0

According to the wiki catalan definition from wiki, I see the expression below: enter image description here

I can understand the first two expressions, but really confused about the third one. The pi symbol stands for the multiply. Does the expression mean the code below:

for (int i = 2; i < n + 1; i++) {
    sum *= (n + i)/i;
}

My code is below

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));
    }
}

}

and I get the result is totally wrong

enter image description here

Anyone help me?

Guy Coder
  • 24,501
  • 8
  • 71
  • 136
Vizi
  • 25
  • 1
  • 7
  • Thank you! But according to this expression, i cannot get the right answer of catalan number, for n=3 I get catalanNumber=4, but it should be 5. what's wrong with my logic? And I did not see anyone do it like this way. They all use recursion way C(n+1)= 2(2n+1)*C(n)/(n+1). @Dukeling. – Vizi Jun 04 '14 at 19:56
  • Change `i < n` to `i <= n`. The pi notation includes the upper value for the iterator, not just those values strictly less than it. – Matt Jun 04 '14 at 20:28

3 Answers3

2

Yes. That's roughly what it means (assuming you initialized sum to 1).

But be careful with integer division. If you write (n + i)/i and both n and i are integers, you might find yourself with some unintended output in certain languages.

For instance, in Java, if n = 3 and i = 2, (n + i)/i = 2, instead of 2.5, since int / int = int and we can't store 2.5 in an integer.

If you cast something double or add a + 0.0 or * 1.0 there somewhere, the result would be a double (double / int = double) and should be correct.

Also keep in mind that sum itself should be a double / float, not an int (because, sum can't store 2.5, similarly to what was mentioned above). If you want the output to be an int, you should Math.round it.

int n = 3;
double product = 1;
for (int i = 2; i <= n; i++) {
   product *= (0.0 + n + i)/i;
}
System.out.println(product); // 5

(I also changed i < n + 1 to i <= n - the latter seems clearer to me, but it doesn't functionally change the code)

For more technical details, see the JLS - Division Operator / and Binary Numeric Promotion.

Bernhard Barker
  • 54,589
  • 14
  • 104
  • 138
1

Yes. Make sure to initialize sum (which should probably be called product) to 1.

Andrew
  • 4,953
  • 15
  • 40
  • 58
0

It's probably safer to use longs or BigIntegers (or an equivalent in whatever language you use) to avoid floating point errors. You can just keep track of the numerator and denominator and divide at the end. (or keep reducing in between steps to reduce chance of overflow)

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;
}

check out a comparison here: https://coderpad.io/565957 using doubles will give you the wrong answer by the time n=30, with gcd mine's only good to 33, but you can easily swap out longs for BigIntegers to go indefinitely.

kyldvs
  • 61
  • 3