2011-05-05 166 views
0

我收到运行以下代码的错误。我提供了评论来描述正在发生的事情。这段代码中导致ArrayIndexOutOfBounds错误的原因是什么?

// 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

堆栈跟踪:1
在btsmall.createTree(btsmall:在线程 “主” java.lang.ArrayIndexOutOfBoundsException

异常。 java:22)
at btsmall.createTree(btsmall.java:31)
at btsmall.gatherOutput(btsmall.j AVA: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输出打印出单一的正方形的,而不是用于在预订的所有节点的值。

+3

通过调试器运行代码,查看引发异常的位置以及发生变量时的状态。 – 2011-05-05 13:20:52

+0

你在哪里设置前序数组的大小?他们不动态调整大小。 – Mikaveli 2011-05-05 13:22:48

+0

@Mikaveli:设置为从System.in中读入的行的大小 – Jeremy 2011-05-05 13:26:28

回答

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

以及第二次以后,该行的实际内容未被使用。我想知道@Jigglypuff是否认为返回的数组是随后的读取更新的......即toCharArray泄漏了一个指针,并且这个数组的大小可以调整... – 2011-05-05 13:30:21

+0

啊我明白了。但是接下来我会如何将readLine()中的字符数组放入预定位而不再读取该行?为什么(预订[i] == 0)检查在行结束时爆炸? – Jigglypuff 2011-05-05 13:30:52

+1

@Jigglypuff:我在答案中添加了更多信息。 – Jeremy 2011-05-05 13:38:33

2

你读了一个空行,所以preorder.length = 0;前序[0]超出界限?

+0

为什么第二行输入是空的?对不起,我还在学习 – Jigglypuff 2011-05-05 13:37:05

+1

也许读者阅读的文字有空行吗? – 2011-05-05 14:53:12

1

你不被初始化的char []在二叉树的构造预购,然后你使用preorder = reader.readLine().toCharArray();

到stote的字符数组,因此不会有大小,因此它抛出ArrayIndexOutOfBouds

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已超过数组长度。

这将是我的猜测,但正如@约翰·托普利指出的那样;调试器是你的朋友。

相关问题