1

现在我不确定是否有人真的可以帮助我解决这个问题,因为要处理的代码量相当可观,但任何帮助都将不胜感激。这是我的相关代码:

public class BTree implements Iterable<String> {
    /** Left child */
    BTree left;
    /** Right Child */
    BTree right;
    /** Comparator to use for sorting */
    Comparator<String> comp;
    /** Parent node */
    BTree parent;
    /** String stored in this leaf */
    String s;
    /** # of iterators currently working on it */
    int active = 0;
    /** Size of the BTree */
    int size;

public void build(Iterable<String> iter, int numStrings) {
        if (this.active > 0) {
            throw new ConcurrentModificationException();
        } 
        else { 
            Iterator<String> itr = iter.iterator();
            while (numStrings != 0 && itr.hasNext()) {
                String s = itr.next();
                if (!this.contains(s)) {
                    this.insert(s);
                    this.size++;
                    numStrings--;
                }
            }
        }
    }

/**
 * Inserts the string into the given BTree
 * @param str - String to insert
 */
private void insert(String str) {
    if (this.s.equals("")) {
        this.s = str;
    }
    else if (this.comp.compare(str, this.s) > 0) {
        if (this.right == null) {
            BTree bt = BTree.binTree(this.comp);
            bt.s = str;
            this.right = bt;
            bt.parent = this;
        } 
        else {
            this.right.insert(str);
        }
    }
    else if (this.comp.compare(str, this.s) < 0) {
        if (this.left == null) {
            BTree bt = BTree.binTree(this.comp);
            bt.s = str;
            this.left = bt;
            bt.parent = this;
        }
        else {
            this.left.insert(str);
        }
    }
}



  private class BTreeIterator implements Iterator<String> {
            /** Current BTree being iterated over */
            BTree current;
            /** How many next() calls have there been */
            int count;
            /** Size of the BTree */
            int max;
            /** Constructor for BTreeIterator
             * @param current
             */
            BTreeIterator(BTree current) {
                this.current = current;
                this.count = 0;
                this.max = current.size;
                active++;
            }

            /** Returns true if there is another string to iterate over
             * @return boolean
             */
            public boolean hasNext() {
                if (this.count != this.max) {
                    return true;
                }
                else {
                    active--;
                    return false;
                }
            }

            /**
             * Returns the next string in the iterator
             * @return String
             */
            public String next() {
                if (this.count == 0) {
                    this.count++;
                    current = this.current.getLeftMost();
                    if (this.current.s.equals("")) {
                        throw new NoSuchElementException();
                    }
                    return this.current.s;
                }
                else if (this.current.right != null) {
                    this.current = this.current.right.getLeftMost();
                    this.count++;
                    return this.current.s;
                }
                else {
                    BTree tree = this.current;
                    while (tree.parent.right == tree) {
                        tree = tree.parent;
                    }
                    this.current = tree.parent;
                    this.count++;
                    return this.current.s;
                }
            }

            /** Throws an exception since we aren't removing anything from the trees
             */
            public void remove() {
                throw new UnsupportedOperationException();
            }

        }
    }

}

异常在while (tree.parent.right == tree)迭代器的 next() 方法中被抛出。有趣的是,我的代码与一个比较器工作得很好,比较器按字典顺序和反向字典顺序对 24000 个单词的文件进行排序。它仅在使用以下比较器时引发异常:

class StringWithOutPrefixByLex implements Comparator<String> {

/**
 * compares o1 and o2
 * @param o1 first String in comparison
 * @param o2 second String in comparison
 * @return a negative integer, zero, or a positive integer 
 *         as the first argument is less than, equal to, or 
 *         greater than the second. 
 */
public int compare(String o1, String o2) {
    String s1, s2;
    if(o1.length() > 4){
        s1 = o1.substring(3);
    }
    else { 
        s1 = o1;
    }
    if(o2.length() > 4){
        s2 = o2.substring(3);
    }
    else { 
        s2 = o2;
    }
    return s1.compareTo(s2);
}
}

更奇怪的是,对于最多 199 个单词的同一文件,它可以与该比较器一起正常工作,但是一旦我将它构建到 200 个单词,它就会中断。

编辑:我已经确定异常是由于代码试图引用tree.parent.rightwhile tree.parentis null,但我无法弄清楚它为什么要这样做。据我所知,我的代码永远不应该尝试调用 null tree.parent,正如我在下面的评论中所解释的那样。

4

1 回答 1

0

好吧,您实际上并没有展示足够多的代码,但是,您的 BTree 的根节点呢?BTree.parent根节点中的值是多少?null?

如果根节点的父节点为空,那么在这个 while 循环中,很可能是:

                while (tree.parent.right == tree) {
                    tree = tree.parent;
                }

... 将到达根节点,tree将设置为tree.parent,即null,然后 while 循环测试将失败,因为tree.parent.right将尝试取消引用空指针。

于 2013-10-19T17:30:12.130 回答