【问题标题】:Java Help Recursion & Binary TreesJava 帮助递归和二叉树
【发布时间】:2015-04-22 14:50:57
【问题描述】:

我对 Java 有点陌生,对递归和二叉树也很陌生。我正在构建一个程序,该程序从文档中获取文本并将其存储在二叉树中。然后我需要取一个字符串并找出它在文本中出现的次数。

我的问题是在添加数据和/或在数据中搜索字符串时。

我决定在每个节点构建时存储字符串和频率。所以我的add方法如下:

public void add(String newWord) {

    //Change the word case to make comparing easier
    newWord = newWord.toUpperCase();


    root = recursiveAdd(root, newWord);
}

/**
 * Takes the root and recurses until the root is null (base case)
 * Frequency is incremented if the data is being added, or if
 * it already exits. If the data is not present, the method recurses
 */
private Node recursiveAdd(Node subTree, String newWord) {

    //Base case: the root is null
    //Empty trees have a node created, set, and incr freq
    if (subTree == null) {  
        subTree = new Node();
        subTree.setStoredWord(newWord);
        subTree.incrFreqCount(); 
        return subTree;

    }


    int comparison = newWord.compareTo(subTree.getStoredWord());

    //For a word already in tree, increment the frequency
    if (comparison == 0) {

        if(newWord.equalsIgnoreCase("translyvania"))
        System.out.println("Entered same word incrementation");

        subTree.incrFreqCount();
        return subTree;

        //The root comes before the new word, then 
        //move on to the right child
    } else if(comparison < 0) {

        subTree.setLchild(recursiveAdd(subTree.getLchild(), newWord));

    } else { //if(comparison > 0) {

        subTree.setRchild(recursiveAdd(subTree.getRchild(), newWord));

    }
    return subTree;
}

我似乎无法说出我的问题出在哪里。对于我正在搜索的单词,有时它说它出现了 16 次(我应该得到的),有时它说 1 次。它似乎根本不一致,并且值似乎无缘无故地发生了变化(尽管我知道肯定有一个)。

一旦我的树建立起来,我就会获取我正在搜索的字符串,并通过这些方法传递它。

public void wordSearch(String lookForWord){

    lookForWord = lookForWord.toUpperCase();
    wordSearchRecur(root, lookForWord);

}



private boolean wordSearchRecur(Node subTree, String lookForWord){

    //Base case
    // The root is that same as the string
    if(subTree == null){
        System.out.println("The word \"" + lookForWord + "\" is not "
                + "found in the text");
        return false;
    }

    int comparison = lookForWord.compareTo(subTree.getStoredWord());

    if(comparison == 0){
        System.out.println("The word \"" + lookForWord + "\" is found " + 
                subTree.getFreqCount() + " times in the text");
        return true;


        //Alphabetically before, then move to left branch
    } else if (comparison < 0){

        System.out.println("move to left");
        return wordSearchRecur(subTree.getLchild(), lookForWord);

        //Alphabetically after, then move to right branch
    } else { // if(comparison > 0){
        System.out.println("move to right");
        return wordSearchRecur(subTree.getRchild(), lookForWord);
    }   

}

我也无法真正理解为什么我会到达 wordSearchRecur() 方法的末尾。我不应该在它到达那一点之前返回吗?我的输出显示它多次到达那里。

我知道我错过了这些概念的大部分内容,但是查看之前的所有帖子并没有帮助。我肯定花了 3 个小时才在 Stack 上寻找答案,更不用说所有其他网站了。

请帮忙!

编辑: 由于@Joop Eggen 的帮助,我编辑了代码以包含我所做的更改,我现在可以在 recursiveAdd() 期间正确计算频率,但在 wordSearchRecur() 期间频率似乎没有跟随节点。即使比较 == 0,freqCount 仍然是 1。

已解决:在@Joop Eggen 的帮助下,进一步的问题只是疏忽的结果。感谢您的帮助。

【问题讨论】:

  • 您将到达递归方法的末尾,因为您应该返回递归调用的结果。 return wordSearchRecur(root.getLchild(), lookForWord);return wordSearchRecur(root.getRchild(), lookForWord);.

标签: java recursion binary-tree


【解决方案1】:

您将从首先将代码简化为最简单的形式中受益。

public void add(String word) {

    //Change the word case to make comparing easier
    word = word.toUpperCase();

    root = recursiveAdd(root, word);
}

/**
 * Takes a sub-tree and recurses until the sub-tree is null (base case)
 * Frequency is incremented if the data is being added, or if
 * it already exists. If the data is not present, the method recurses
 */
private Node recursiveAdd(Node subtree, String word) {

    // Base case: the subtree is null
    if (subtree == null) {
        Node node = new Node();
        node.setStoredWord(word);
        node.incrFreqCount();
        return node;
    }

    int comparison = word.compareTo(subtree.getStoredWord());
    if (comparison == 0) {
        // For data already in tree, increment the frequency
        subtree.incrFreqCount();
    } else if (comparison  < 0) {
        subtree.setLchild(recursiveAdd(subtree.getLchild(), word);
    } else /*if (comparison > 0)*/ {
        subtree.setRchild(recursiveAdd(subtree.getRchild(), word);
    }
    return subtree;
}

也搜索:

public void wordSearch(String lookedForWord){   
    lookedForWord = lookedForWord.toUpperCase();
    wordSearchRecur(root, lookedForWord);
}

private boolean wordSearchRecur(Node subtree, String word){

    if (subtree == null) {
        System.out.println("The word \"" + word + "\" is not "
                + "found in the text");
        return false;
    }

    int comparison = word.compareTo(root.getStoredWord();
    if (comparison == 0){
        System.out.println("The word \"" + word + "\" is found " + 
                subtree.getFreqCount() + " times in the text");
        return true;
    } else if (comparison < 0) {
        return wordSearchRecur(subtree.getLchild(), word);
    } else /*if (comparison > 0)*/ {
        wordSearchRecur(subtree.getRchild(), word);
    }   
}

这有助于避免错误,因为要检查/出错的情况更少。

正如您在这两种情况下所做的 toUpperCase 一样,并且在重写中,比较也是相同的(您有 equals 并转过 compareTo 参数,一切都应该工作。

实际上显示的代码看起来还不错。做一个递归的dumpTree(Node subtree, String indentation)。并检查每一步。

可能你在这里稍微修改了代码,原来一些大括号{ }放错了位置。

【讨论】:

  • 这样就容易多了!它清除了很多,我现在 wordSearchRecur() 提出了与 recursiveAdd() 提出的相同的 freqCount。但是,从调试中我可以看到,在 recursiveAdd() 期间,它只额外输入了 (comparison == 0) 块 1 次。我现在的频率是 2 而不是 16。
  • 糟糕...我收回了。它的频率仍然是 1。
【解决方案2】:

在以下任何一种情况下,您都不会返回:

//Alphabetically before, then move to left branch
if(lookForWord.compareTo(root.getStoredWord()) < 0){
    System.out.println("move to left");
    wordSearchRecur(root.getLchild(), lookForWord);

//Alphabetically after, then move to right branch
} else if(lookForWord.compareTo(root.getStoredWord()) > 0){
    System.out.println("move to right");
    wordSearchRecur(root.getRchild(), lookForWord);
}   

你需要return wordSearchRecur,而不是仅仅调用它并丢弃结果。

【讨论】:

  • 我发布了相同的评论而不是答案,因为它没有解释为什么For the word that I am searching, sometimes it says that it occurs 16 times(what I should get) and sometimes it says 1 time.
  • 感谢您的帮助。这解决了最后一次返回的问题。那部分更有意义。不过,我仍然被困在另一个问题上。
  • @learned.beh 修复回报可能已经修复了它,但如果你不知道你做了什么改变以使其中断/工作,那么我真的无法帮助你。您需要确定有效的方法、无效的方法以及它们之间的区别。
猜你喜欢
  • 2016-07-20
  • 2010-12-07
  • 1970-01-01
  • 2013-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-19
相关资源
最近更新 更多