KMonkey
KMonkey

Reputation: 27

Recursion method leads to stack overflow in Java program

So the premise of my program is that it's a JavaFX GUI that will display the results of "analysis".

I have 6 different strings ranging from length 1 to length 3

String[] phrases = new String[] { "ar", "ne", "um", "ll", "r", "ose" };

as well as an arrayList of objects of which I only use the name (String value).

So far I've been able to set up the loop that feeds in the data to display the GUI.

private void analyzePlantMenu(ArrayList<Plant> plants)
{
    String[] phrases = new String[] { "ar", "ne", "um", "ll", "r", "ose" };
    BorderPane sects = new BorderPane();

    String current = "";
    TextArea analysis = new TextArea();

    for (Plant myplant : plants)
    {
        current = myplant.getName();
        for (int q = 0; q < phrases.length; q++)
        {
            String trial = phrases[q];
            analysis.appendText("The number of times " + phrases[q] + " appeared in the word " + current + " were "
                    + compareTrials(trial, current) + "\n");
        }
    }

The trouble I'm having is returning the correct value for compareTrials

Here's the recursive method I have so far

private int compareTrials(String trial, String current)
{
    int shift2 = 0 + trial.length();
    int shift = 0;
    if (shift == current.length())
    {
        return 0;
    }
    else if (current.substring((shift), (shift2)).contains(trial))
    {
        shift2 += 1;
        shift += 1;
        return 1 + compareTrials(trial, current);
    }
    else
    {
        shift2 += 1;
        shift += 1;
        return 0 + compareTrials(trial, current);
    }
}

Can someone help me understand why I'm getting a stack overflow error when iterating through the word?

My best guess is that it's either because my base case isn't THE base case or I have my else statement in a way that it'll go on indefinitely

Edit

The way I went about changing my method to detect these values and not go into stack overflow involved moving multiple variables outside of the compareTrials method and passing them in instead. Cosmetic changes and edited code below

private void analyzePlantMenu(ArrayList<Plant> plants)
{
    String[] phrases = new String[] { "ca", "in", "us", "ll", "r", "ose" };
    BorderPane sects = new BorderPane();

    String current = "";
    TextArea analysis = new TextArea();

    for (Plant myplant : plants)
    {
        current = myplant.getName();
        for (int q = 0; q < phrases.length; q++)
        {
            String trial = phrases[q];
                **int total = 0;
                int shift2 = trial.length();
                int shift = 0;**
            analysis.appendText((q+1) + ". The number of times " + phrases[q] + " appeared in the word " + current
                    + " were " + compareTrials(trial, current, shift, shift2, total) + "\n");
        }
        analysis.appendText("Finished analysis of " + current.toUpperCase() + "\n");
        analysis.appendText("\n");
    }

And the recursion method

private int compareTrials(String trial, String current, int shift, int shift2, int total)
{
    if (shift2 >= current.length() + 1)
    {
        System.out.println(shift + " " + shift2);
        return total += 0;
    }
    else if (current.substring((shift), (shift2)).equalsIgnoreCase((trial)))
    {
        System.out.println(shift + " " + shift2);
        return total += 1 + compareTrials(trial, current, shift + 1, shift2 + 1, total);
    }
    else
    {
        System.out.println(shift + " " + shift2);
        return total += 0 + compareTrials(trial, current, shift + 1, shift2 + 1, total);
    }
}

Upvotes: 0

Views: 94

Answers (3)

neomega
neomega

Reputation: 732

From what i understand of your needs, i would go with something like this for a recursive method:

private int compareTrials(String trial, String current, int startIndex) {
    int nextIndex = current.indexOf(trial, startIndex);
    if(nextIndex == -1) {
        return 0;
    }
    return 1 + compareTrials(trial, current, nextIndex + trial.length());
}

And the first call would be with a startIndex of 0.

Upvotes: 1

timrau
timrau

Reputation: 23058

Your two recursive calls,

    return 1 + compareTrials(trial, current);

and

    return 0 + compareTrials(trial, current);

have parameters exactly the same as incoming parameters. trial and current are never changed. Thus, you cannot expect it to converge, and thus it just call compareTrials() for infinite times with the same parameters.

Upvotes: 4

Colin
Colin

Reputation: 329

I believe your issue is stemming from the fact that whenever you recursively call compareTrials(). Basically what you are doing in each of the return methods is just calling the recursive method again with the same method parameters. So it's just an infinite "loop".

I'd start by redefining trial and current and then calling the compareTrials() method with those modified parameters.

Upvotes: 1

Related Questions