【问题标题】:ArrayIndexOutOfBoundsException: 5 Not making any sense?ArrayIndexOutOfBoundsException: 5 没有任何意义?
【发布时间】:2014-02-25 21:31:37
【问题描述】:

这是我的两个课程:

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class TopoSort {

    public static void main(String[] args) throws FileNotFoundException {

        File textFile = new File("graphs.txt");
        Scanner in = new Scanner(textFile);


        int numGraphs = in.nextInt();
        for(int i=0;i<1;i++)
        {
            int nodeNum = in.nextInt();
            tsMakeGraph graph1 = new tsMakeGraph(nodeNum);

            int[][] adjArray = new int[nodeNum][nodeNum];
            for(int j=0;j<nodeNum;j++)
            {

                for(int k=0;k<nodeNum;k++)
                {
                    adjArray[j][k] = in.nextInt();
                }

                for(int n=0;n<nodeNum;n++)
                {
                    graph1.addNode(n);
                }


            }

            for(int j=0;j<nodeNum;j++)
            {
                for(int k=0;k<nodeNum;k++)
                {
                    if(adjArray[j][k] == 1)
                    {
                        graph1.makeEdge(j, k);
                    }
                }
            }

            graph1.topologicalSort();

        }
    }
}

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;

public class tsMakeGraph {

    private Node nodeList[];
    private int adjMatrix[][];
    private int numNodes;
    private int topoArray[];

    public tsMakeGraph(int nodeNum) {
        nodeList = new Node[nodeNum];
        adjMatrix = new int[nodeNum][nodeNum];
        numNodes = 0;
        for (int i = 0; i < nodeNum; i++) {
            for (int k = 0; k < nodeNum; k++) {
                adjMatrix[i][k] = 0;
            }
        }
        topoArray = new int[nodeNum];
    }

    public void addNode(int i) {
        nodeList[numNodes++] = new Node(i);

    }
}

当我通过 for 循环添加节点时出现越界错误,但如果我通过绑定 graph1.addNode(0)、graph1.addNode(2)、graph1.addNode(3) 手动添加节点),graph1.addNode(numNodes),它会工作。这对我来说没有意义,我一直在绞尽脑汁哈哈。顺便说一句,我编辑了我的大部分地形图类,因为这是一个硬件项目。

【问题讨论】:

  • 你从异常回溯中知道异常的来源。在失败操作之前添加 System.out.println 调用以转储数组索引和数组 .length 值。有些事情会让你大吃一惊。
  • for(int i=0;i&lt;1;i++)
  • 我看不出有什么明显的错误。异常发生在哪一行?顺便说一句,将 adjMatrix 的每个元素设置为 0 的 tsMakeGraph 构造函数中的循环是不必要的;新的数值数组元素已经是 0。
  • 您的 j 和 n 索引 for 循环嵌套在 TopoSort 中,因此您尝试将 nodeNum*nodeNum 元素添加到大小为 nodeNum 的数组 (graph1.nodeList) 中。使用 ArrayList 代替 nodeList?
  • @fge 好吧,它会运行一次,也许他只是在测试一次迭代:) 请发布错误行,这样可以更容易地查明错误。这不能太难调试..

标签: java arrays list indexoutofboundsexception


【解决方案1】:

缩短代码一点你有这个:

for(int j=0;j<nodeNum;j++)
{
    for(int n=0;n<nodeNum;n++)
    {
         graph1.addNode(n);
    }
}

public class tsMakeGraph {

    public tsMakeGraph(int nodeNum) {
        nodeList = new Node[nodeNum];
    }

    public void addNode(int i) {
        nodeList[numNodes++] = new Node(i);
    }
}

所以这里发生的情况是您有一个包含 nodeNum 元素的数组,但您正尝试向其中添加 nodeNum^2 次。

我不知道告诉您“正确”解决方案的目的是什么。如果nodeList 应该与adjMatrix 具有相同数量的元素,那么您应该像new Node[nodeNum * nodeNum] 一样实例化它。 (与topoArray 相同?)或者如果nodeList 应该包含整数0...nodeNum-1,那么您应该将其拉出嵌套循环。

【讨论】:

    【解决方案2】:

    您的 j 和 n 索引 for 循环嵌套在 TopoSort 中,因此您尝试将 nodeNum*nodeNum 元素添加到大小为 nodeNum 的数组 (graph1.nodeList) 中。

    您可以消除一个循环,因为从 0 到 nodeNum 有两个循环:

    tsMakeGraph graph1 = new tsMakeGraph(nodeNum); 
    
    int[][] adjArray = new int[nodeNum][nodeNum];
        for(int j=0;j<nodeNum;j++) {
            for(int n=0;n<nodeNum;n++) { // there was no need for two for loops here
                adjArray[j][k] = in.nextInt();
                graph1.addNode(n);
            }
        }
    

    并使nodeList 大小为nodeNum*nodeNum:

    public tsMakeGraph(int nodeNum) {
        nodeList = new Node[nodeNum*nodeNum];
        adjMatrix = new int[nodeNum][nodeNum];
        numNodes = 0;
    
        //adjMatrix values will be 0 by default, don't need to manually do that
    
        // this might need to be nodeNum*nodeNum as well, not used in your question
        // if you get another out of bounds error later, remember this!
        topoArray = new int[nodeNum]; 
    }
    

    我还将您对 adjMatrix 中每个值的手动设置删除为 0,因为 0 无论如何都是默认值,并且 O(n^2) 操作对于大量节点可能会变得非常昂贵。

    也许考虑使用 ArrayList 代替 nodeList(除非你的作业禁止这样做)。实际上,从 j 循环中拉出循环可能会更好,否则您将拥有每个节点的 nodeNum 副本。不确定您的使用情况,所以我无法真正帮助您。

    请记住,如果 nodeList 的大小错误,topoArray 也可能是。

    【讨论】:

      【解决方案3】:

      当您使用此代码添加节点时:

      for(int j=0;j<nodeNum;j++)
      {
          for(int n=0;n<nodeNum;n++)
          {
              graph1.addNode(n);
          }
      }
      

      您实际上是在添加节点 nodeNum*NodeNum 次。例如,如果节点 num 为 2,则添加节点 2*2 = 4 次。

      但是,当您像这样初始化 nodeList 数组时:

      nodeList = new Node[nodeNum];
      

      您只是将其设置为 nodeNum 大小。因此,如果 nodeNum 为 2,则您的数组只能保存 2 个值。但是由于添加时的代码:

      nodeList[numNodes++] = new Node(i);
      

      您将 numNodes 递增 4 次。这导致了越界错误。

      像这样初始化你的 nodeList 数组:

      nodeList = new Node[nodeNum*nodeNum];
      

      应该解决问题

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-05-07
        • 1970-01-01
        • 2023-01-02
        • 1970-01-01
        • 2020-11-30
        • 2020-08-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多