简体   繁体   中英

Keep Getting Error For Ackermans Function

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM