使用arraylist的递归方法的stackoverflower

时间:2012-03-19 14:16:18

标签: java algorithm data-structures recursion trie

我在线程“main”java.lang.StackOverflowError中看到一个Exception。我希望知道下面的代码有什么问题。

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

2 个答案:

答案 0 :(得分:6)

本质上,堆栈溢出来自于这样一个事实,即你的方法不断被递归调用,递归永远不会结束。

一个可能的问题是这个电话:

addWord(word,temp,pos++);

相当于

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

你可能意味着:

addWord(word,temp,++pos);

这相当于

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

答案 1 :(得分:0)

我写了一个更简单的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);

}

代码中的原始版本在基本情况和递归调用方面存在一些问题。作为一般规则,您应该避免更改方法参数的值(pos++部分)。

我猜你正在构建一个Trie数据结构,我预计你会遇到terminus属性的问题。想一想,如果你添加几个带有公共前缀的单词,那么这将是终结节点?您是否打算在同一级别添加具有相同letter的多个节点,或者您是否希望使用相同的字母共享同一级别的节点?在后一种情况下,terminus属性的值是什么?

为了明确我的观点,请绘制一个图表,显示在执行以下代码后您希望Trie看起来如何(密切关注每个节点中terminus的值),并查看上述内容实现给出了您期望的结果。

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