Search code examples
javarecursionstack-overflow

StackOverFlowError in java program


I am trying to solve a problem which asks to find the smallest prime palindrome, which comes after a given number which means that if the input is 24, the output would be 101 as it is the smallest number after 24 which is both prime and a palindrome.

Now my code works perfectly for small values but the moment I plug in something like 543212 as input, I end up with a StackOverFlowError on line 20, followed by multiple instances of StackOverFlowErrors on line 24. Here is my code :

package nisarg;
import java.util.Scanner;

public class Chef_prime_palindromes {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        long num = input.nextLong();
        isPalindrome(num + 1);
    }

    public static boolean isPrime(long num) {
        long i;
        for (i = 2; i < num; i++) {
            if (num % i == 0) {
                return false;
            }
        }
        return true;
    }

    public static void isPalindrome(long num) {
        String word = Long.toString(num);
        int i;
        for (i = 0; i < word.length() / 2; i++) {
            if (word.charAt(i) != word.charAt(word.length() - i - 1)) {
                isPalindrome(num + 1);
            }
        }
        if (i == word.length() / 2) {
            if (isPrime(num)) {
                System.out.println(num);
                System.exit(0);
            } else {
                isPalindrome(num + 1);
            }
        }
    }
}

Solution

  • A new String object is created in each recursive call and placed onto stack (the place where all variables created in methods are stored until you leave the method), which for a deep enough recursion makes JVM reach the end of allocated stack space.

    I changed the locality of the String object by placing it into a separate method, thus reducing its locality and bounding its creation and destruction (freeing of stack space) to one recursive call.

    package com.company;
    
    import java.util.Scanner;
    
    public class Chef_prime_palindromes {
        public static void main(String[] args) {
            Scanner input = new Scanner(System.in);
            long num = input.nextLong();
            isPalindrom(num + 1);
        }
    
        public static boolean isPrime(long num) {
            long i;
            for (i = 2; i < num; i++) {
                if (num % i == 0) {
                    return false;
                }
            }
            return true;
        }
    
        private static void isPalindrom(long num) {
            for (; ; ) {
                if (isPalindrome(num)) {
                    if (isPrime(num)) {
                        System.out.println(num);
                        System.exit(0);
                    } else {
                        num++;
                    }
                } else {
                    num++;
                }
            }
        }
    
        public static boolean isPalindrome(long num) {
            String string = String.valueOf(num);
            return string.equals(new StringBuilder(string).reverse().toString());
        }
    }