Search code examples
javarecursiontext-filesstack-overflowoutputstream

How do you resolve a StackOverflowError while using recursion in Java?


I am currently writing a program that will compute the moves needed to be taken in the Tower of Hanoi problem. I need to write all the moves taken to an output .txt file.

When I try to do this I keep keeping a StackOverFlow error once at the beginning of the if statement in the towerOfHanoiMoves method and multiple times at the first recursive call to that same method.

I'm guessing the error has to do with the outStream and passing it each time to the method, but I am not sure. If that is the case, I cannot figure out how I would be able to write to the same output file given by the user in the main method.

Also the code will always print the information from the "finally" statement in the try catch block, and the outStream statement in the if statement, but nothing else.

I've tried to flush the outStream after using the outStream.write commands in the towerOfHanoiMoves method but that did not help at all.

Also I've imported all the libraries for the BufferedReader, FileReader, etc. but they won't show up properly in my question. So they are in the code just so you know, but they just don't appear in the code here.

public class TowerofHanoiRecursive {

    public static void main(String[]args)throws IOException,
    EmptyFile,
    FileNotFoundException {
        int n; //number of disks in tower
        String rodLeft = "A",
        rodRight = "C",
        rodMiddle = "B";
        FileReader inputStream = null;
        FileWriter outputStream = null;
        BufferedReader str = null;

        try {
            outputStream = new FileWriter(args[1]); // output file
            inputStream = new FileReader(args[0]); // input file
            str = new BufferedReader(inputStream);
            String nextLine;
            File newFile = new File(args[0]);

            if (newFile.length() == 0) { //Tests if input file is empty
                throw new EmptyFile("Input file is empty.");

            }
            while ((nextLine = str.readLine()) != null) {
                outputStream.write("----------------------------------------"
                     + "------------------------\n");
                outputStream.write("Number of Disks in Starting Tower = "
                     + nextLine);
                n = Integer.parseInt(nextLine);

                towerOfHanoiMoves(n, rodLeft, rodRight, rodMiddle,
                    outputStream);

            }

        } catch (FileNotFoundException e) {
            outputStream.write("Input file not found.");
            outputStream.flush();
            if (outputStream != null)
                outputStream.close();

        }
        catch (EmptyFile e) {
            outputStream.write(e.getMessage());
            outputStream.flush();
            if (inputStream != null)
                inputStream.close();
            if (outputStream != null)
                outputStream.close();
            str.close();

        }
        finally {
            outputStream.write("");
            outputStream.write("Total time to taken to solve Tower: ");
            outputStream.write("\n\nSuccess!");
            outputStream.flush();

            if (inputStream != null)
                inputStream.close();
            if (outputStream != null)
                outputStream.close();
            str.close();
        }

    }

    public static void towerOfHanoiMoves(int n, String srcRod, String destRod,
        String spareRod, FileWriter outStream) {
        try {
            if (n == 1) {
                outStream.write("\nMove disk 1 from rod " + srcRod + " to rod "
                     + destRod + ".");
            }
            towerOfHanoiMoves(n - 1, srcRod, spareRod, destRod, outStream);
            outStream.write("\nMove disk " + n + " from rod " + srcRod
                 + " to rod " + destRod + ".");
            towerOfHanoiMoves(n - 1, spareRod, destRod, srcRod, outStream);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Solution

  • if (n == 1) {
        outStream.write("\nMove disk 1 from rod " + srcRod + " to rod + destRod + ".");
    } else {
       ...
    }
    

    or add another break condition

    basically you were going into the negative values with n

    PS having a debugger helps that way you can go step by step through your code ad check the variables or simply System.out.println variables at every step