1
import java.util.Scanner;

//create AckermannsFunction class
public class Ackermann
{
   public static void main(String[] args) {

      //instance variables
      String input; //holds user input for the numbers
      int num1; //holds first number
      int num2; //holds second number

      //create new Scanner
      Scanner keyboard = new Scanner(System.in);

      do {
         //get first number from user
         System.out.println("Enter a number: ");
         input = keyboard.nextLine();
         num1 = Integer.parseInt(input);

         //get second number from user
         System.out.println("Enter another number: ");
         input = keyboard.nextLine();
         num2 = Integer.parseInt(input);

         System.out.println("Result: \n Ackermann: (" + num1 + "," + num2 + ") = " + ackermann(num1, num2));
      }

      //while(Integer.parseInt(input) != -1);
      while(num1 != -1 || num2 != -1);

      System.out.println("Bye!");
   }

   public static int ackermann(int m, int n) {
      //calculate if m = 0
      if(m == 0)
         return n + 1;
      if(n == 0)
         return ackermann(m - 1, 1);
      else
         return ackermann(m - 1, ackermann(m, n - 1));
   }
}

Heres the error I keep getting:

Exception in thread "main" java.lang.StackOverflowError
    at Ackermann.ackermann(Ackermann.java:44)

This goes on many times whenever I input -1 for first number and -1 for the second. I know it has to do with the while loop and have tried many ways to fix it but can't think of a better way to do so.

  • The Ackerman method only applies to non-negative inputs, so you should throw an exception if non-negative inputs are entered. – Gregory Basior Feb 21 '15 at 01:42

2 Answers2

1

Your ackermann method's base case, which is responsible for terminating the recursion does not deal with numbers smaller than zero, so you keep going into the else clause infinitely, or until you run out of stack, whichever comes first....

  public static int ackermann(int m, int n) {
      if(m == 0)  <--nope
         return n + 1;
      if(n == 0) <--nope
         return ackermann(m - 1, 1);
      else
         return ackermann(m - 1, ackermann(m, n - 1)); <-- here we go again
   }

I don't remember the precise definition of the ackermann function, but you could easily prevent the StackOverflowError when m < 0 with:

  public static int ackermann(int m, int n) {
      if(m <= 0)
         return n + 1;
      if(n == 0)
         return ackermann(m - 1, 1);
      else
         return ackermann(m - 1, ackermann(m, n - 1));
   }
Amir Afghani
  • 37,814
  • 16
  • 84
  • 124
  • Thank you that helped so much. I kept thinking it had something to do-while loop. Guess i have a bit more studying on the Ackermann function. – 13lank_null Feb 21 '15 at 01:32
1
  1. By the way, you'll still get Stack Overflow Error for greater arguments(m > 3 and n > 12 with default stack size) because even for Ackermann(3,15) we have 45811673828 function calls but to compute Ackermann(3,16) we need max stack size > 10 mb
  2. Ackermann(4,2) = 2^65536-3, so int type is not enough to represent this huge number (19 729 decimal digits). You may to use BigDecimal or something similar.