简体   繁体   中英

stackoverflowerror on recursive method with arraylist

I am see an Exception in thread "main" java.lang.StackOverflowError. I hope to know what is wrong with the code below.

public void addWord(String word){
    addWord(word,root,0);
}

private void addWord(String word,Node root,int pos)
{
    for(Node c:root.children)
    {
        if(word.charAt(pos)==c.letter)
        {
            addWord(word,c,pos++);
        }
    }
    Node temp = new Node();
    temp.letter=word.charAt(pos);
    temp.children=new ArrayList<Node>();
    root.children.add(temp);
    if(pos==word.length()-1)
    {
        temp.terminus=true;
        return;
    }
    if(pos<word.length()-1)
    {
        addWord(word,temp,pos++);
    }
}

In essence, stack overflow comes from the fact that your method keeps being called recursively and the recursion never ends.

One possible problem is this call:

addWord(word,temp,pos++);

It is equivalent to

addWord(word,temp,pos);
pos = pos + 1;

You probably mean:

addWord(word,temp,++pos);

which would be equivalent to

pos = pos + 1;
addWord(word,temp,pos);

I wrote a simpler version of addWord() :

private void addWord(String word, Node aRoot, int pos) {

    if (pos == word.length())
        return;

    for (Node c : aRoot.children) {
        if (word.charAt(pos) == c.letter) {
            addWord(word, c, pos+1);
            return;
        }
    }

    Node temp = new Node();
    temp.letter = word.charAt(pos);
    temp.children = new ArrayList<Node>();
    temp.terminus = pos == word.length() - 1;

    aRoot.children.add(temp);
    addWord(word, temp, pos+1);

}

The original version in your code had a couple of problems with base cases, and with the recursive calls. As a general rule, you should avoid changing the values of a method's parameters (the pos++ part).

I'm guessing you're building a Trie data structure, and I anticipate that you're gonna have problems with that terminus attribute. Think about it, if you add several words with common prefixes, which would be the terminus node? do you intend to add several nodes with the same letter at the same level, or do you want to share nodes at the same level with the same letter? in the latter case, what would be the value of the terminus attribute?

To make my point clear, draw a diagram showing how would you like your Trie to look like after executing the following code (paying close attention to the value of terminus in each node), and see if the above implementation gives the result you expect.

Test t = new Test();
t.addWord("a");
t.addWord("abc");
t.addWord("ab");

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