0

My main goal is to compute the Stirling number of the second kind with an input of 1 to 500. Without using the BigInteger option/import, the code works flawlessly but the moment I use the said import, I encounter java.lang.StackOverFlowError because of BigInteger k (I tried converting it to d out of desperation).

Hope someone can help. And if possible, please point out other errors if you will spot any. Thank you!

import java.util.*;
import java.math.*;
public static void main(String[] args) {
Scanner sc = new Scanner (System.in);
try{
System.out.print("Please enter the r: ");
BigInteger n = sc.nextBigInteger();
System.out.print("Please enter the n: ");
BigInteger k = sc.nextBigInteger();

BigInteger constant= new BigInteger("0");
BigInteger result = new BigInteger("1");
BigInteger result2 = new BigInteger("500");

    int result3 = n.compareTo(result);
    int result4 = n.compareTo(result2);
    int result5 = k.compareTo(result);
    int result6 = k.compareTo(result2);
    int result7 = n.compareTo(constant);
    int result8 = k.compareTo(constant);



if (result3 == -1 || result4==1){
    System.out.println("n must be 1 to 500");
}
if (result5 ==-1 || result6 == 1){
    System.out.println("k must be 1 to 500");
}
else if (result7 == 1 && result4 == -1 && result8 == 1 && result6 == -1){
System.out.println("The answer is: " + StirlingFunction(n, k));
}
}

catch(InputMismatchException a){
    System.out.println("The input must be an integer.");
}
}


public static BigInteger StirlingFunction(BigInteger n, BigInteger k){
   BigInteger d= new BigInteger("0").add(k);
   BigInteger a = BigInteger.ONE;
   if (k.compareTo(BigInteger.ONE) == 0 || k == n){
      return BigInteger.ONE;
   }

   else{
    BigInteger x = (StirlingFunction(n.subtract(a), d));
    BigInteger y = (StirlingFunction(n.subtract(a), k.subtract(a)));

   return k.multiply(x).add(y);

    }
}

}

This is the result/output

1 Answers1

1

Revised to answer what was wrong.

k==n

is never true because they are different objects, so your code never hit its base case. Changing it to

`k.equals(n)`

made your code give the right answer quickly, with no error.

The following translated from the post at Recursive functions for partitions, stirling numbers, and chebyshev polynomials of the first may or may not be helpful. I tried to keep things as close to that and as simple as possible, while pretty much emulating your code.

public static BigInteger StirlingFunction(BigInteger n, BigInteger k){
   if (BigInteger.ZERO.equals(n) && BigInteger.ZERO.equals(k)){
       return BigInteger.ONE;
   }
   //still here, not both zero
   if (BigInteger.ZERO.equals(n) || BigInteger.ZERO.equals(k)){
       return BigInteger.ZERO;
   }
   BigInteger x = StirlingFunction(n.subtract(BigInteger.ONE), k);
   BigInteger y = StirlingFunction(n.subtract(BigInteger.ONE), k.subtract(BigInteger.ONE));
   //S2(n, k) = k * S2(n - 1, k) + S2(n - 1, k - 1)
   return k.multiply(x).add(y);

    }
Jeremy Kahan
  • 3,796
  • 1
  • 10
  • 23
  • Thank you very much! The code works flawlessly but is there any possible way to compute large numbers like n=300 k=150? I tried using the said code but still, it doesn't compute large numbers Edit: The code works for large numbers. But runs at a very slow pace. Any suggestion to speed up the pace of showing the output? Thank you very much! – Krissoel Jon Morales Nov 17 '19 at 06:12
  • I am sorry, but I do not know. I am wondering if that recursion would blow the call stack, in which case maybe the explicit formula would be better (though dividing by 150! seems like a crazy big number). Also probably worth using https://www.geeksforgeeks.org/space-and-time-efficient-binomial-coefficient/ – Jeremy Kahan Nov 17 '19 at 06:28
  • Sure. Good news. Without any fast factorial tricks (except not using recursion), 150! took .29 seconds on https://www.jdoodle.com/online-java-compiler/. – Jeremy Kahan Nov 17 '19 at 06:41