是什么导致此代码中的ArrayIndexOutOfBounds错误?

时间:2011-05-05 13:09:58

标签: java arrays tree binary-tree

运行以下代码时出错。我提供了评论来描述正在发生的事情。

// Node
class TreeNode {
    char value;
    TreeNode left;
    TreeNode right;
}

// Main class
public class BinaryTree {
    // Global variables
    char[] preorder;
    int i = 0;

    // Main method runs gatherOutput
    public static void main(String[] args) throws IOException {
        new BinaryTree().gatherOutput();
    }

    // This takes a null tree as input from the gatherOutput method
    // and whenever a 0 is encountered in the preorder character array
    // (from a string from System.in) a new external node is created with
    // a value of 0. Whenever a letter is encountered in the character
    // array, a new internal node is created with that letter as the value.
    //
    // =====ArrayOutOfBoundsException occurs somewhere here=====
    //
    public TreeNode createTree(TreeNode tree) throws IOException {
        if (preorder[i] == 0) {
            tree = new TreeNode();
            tree.value = 0;
            tree.left = tree.right = null;
            i++;                
        } else {
            tree = new TreeNode();
            tree.value = preorder[i];
            i++;
            createTree(tree.left);
            createTree(tree.right);
        }
        return tree;
    }


    // Supposed to print out contents of the created binary trees.
    // Just for testing purposes, but it's not working right now for some reason.
    public void preorderTraversal(TreeNode tree) {
        if (tree != null) {
            System.out.println(tree.value + " ");
            preorderTraversal(tree.left);
            preorderTraversal(tree.right);
        }
    }

    // Reads System.in for the Strings used in making the binary tree
    // and is supposed to make a different binary tree for every line of input
    public void gatherOutput() throws IOException {
        TreeNode tree = null;

        InputStreamReader input = new InputStreamReader(System.in); 
        BufferedReader reader = new BufferedReader(input);

        preorder = reader.readLine().toCharArray();

        while (reader.readLine() != null) {
            tree = createTree(tree);
            preorderTraversal(tree);
            i = 0;
        }
    }
}

每当我有多行输入时,我都会收到一个ArrayIndexOutOfBounds错误。例如:

  

b
  B'/ P>

堆栈追踪:

  

线程“main”中的异常java.lang.ArrayIndexOutOfBoundsException:1
          在btsmall.createTree(btsmall.java:22)
      在btsmall.createTree(btsmall.java:31)
      在btsmall.gatherOutput(btsmall.java:53)
      在btsmall.main(btsmall.java:18)

它发生在createTree方法中,但我无法确定原因。即使我只有一行输入,preorderTraversal方法似乎也没有运行,因为我没有运行程序的输出,但我不知道为什么。有人可以帮帮我吗?

感谢。

编辑:我对以下两种方法进行了更改,并且不再出现ArrayIndexOutOfBounds错误。

public void createTree(TreeNode tree) throws IOException {
    if (i >= preorder.length) {
        i++;
    } else if (preorder[i] == '0') {
        tree = new TreeNode();
        tree.value = '0';
        tree.left = tree.right = null;
        i++;                
    } else {
        tree = new TreeNode();
        tree.value = preorder[i];
        i++;
        createTree(tree.left);
        createTree(tree.right);
    }
}

public void gatherOutput() throws IOException {
    InputStreamReader input = new InputStreamReader(System.in); 
    BufferedReader reader = new BufferedReader(input);

    String line = null;
            TreeNode tree = new TreeNode();
    while ((line = reader.readLine()) != null) {
        preorder = line.toCharArray();
        tree = createTree(tree);
        preorderTraversal(tree);
        i = 0;
    }
}

然而,preorderTraversal的输出打印出一个正方形而不是预先排序的所有节点的值。

4 个答案:

答案 0 :(得分:3)

这里发生的事情很少。最突出的是你正在阅读一条线,然后立即尝试读取另一条线,如下所示。

preorder = reader.readLine().toCharArray();

while (reader.readLine() != null) {

你只需要读一次这一行。例如:

String line = null;
while ((line=reader.readLine()) != null){
    System.out.println(line);
    preorder = line.toCharArray();
}

另外,您的支票:

if (preorder[i] == 0) {
当你到达行尾时,

会爆炸,因为你永远不会检查i是否超出数组的范围。我不确定你想要检查那里的东西。

答案 1 :(得分:2)

你读了一个空行,所以preorder.length = 0;预订单[0]超出范围?

答案 2 :(得分:1)

您没有在二进制树的构造函数中初始化 char []预订,然后您正在使用preorder = reader.readLine().toCharArray();

表示char数组,因此它没有大小所以抛出 ArrayIndexOutOfBouds

答案 3 :(得分:1)

看起来您的代码首先会进入else语句:

if (preorder[i] == 0) {
        tree = new TreeNode();
        tree.value = 0;
        tree.left = tree.right = null;
        i++;                
    } else {
        tree = new TreeNode();
        tree.value = preorder[i];
        i++;
        createTree(tree.left);
        createTree(tree.right);
    }

然后你增加i并调用createTree(tree.left) i超过数组长度。

这是我的猜测,但正如@John Topley指出的那样;调试器是你的朋友。