首页 > 解决方案 > 深度优先搜索和字符串索引超出范围:-3

问题描述

使用我自己没有编写的 GraphRead-Class,我将完成深度优先搜索算法来编辑文本文件中的图形。

这是类的样子:

public class GraphRead {

    public static Graph<Vert,Edge<Vert>> FileToGraph(String dat, boolean directed, boolean standardIds, boolean weighted) {
        FileInputStream fis = null;
        Graph<Vert,Edge<Vert>> G = null;
        try {
          fis = new FileInputStream(dat);
        }
        catch ( Exception e) {
            System.out.println(dat + " couldn't be opened");
            System.out.println(e.getMessage());
        }
        try {
              InputStreamReader isr   = new InputStreamReader(fis);
              BufferedReader    br = new BufferedReader   (isr);

              // read number of vertices
              String aRow;
              aRow = br.readLine();
              int n = new Integer(aRow);

              // read number of edges
              aRow = br.readLine();
              int m = new Integer(aRow);

              // construct graph
              G = new Graph<Vert,Edge<Vert>>(n, directed);

              if (!standardIds) { // vertices have arbitrary ids and get a name
                  // read vertices (1. substring: id, 2. substring: name)
                  for (int i = 1; i <= n; i++) {
                      aRow = br.readLine();
                      int sepIndex1 = aRow.indexOf(' ');
                      String vId = aRow.substring(0, sepIndex1);
                      String vStr = aRow.substring(sepIndex1+ 1, aRow.length());
                      int id = new Integer(vId);
                      Vert v = new Vert(id,vStr);
                      G.addVertex(v);
                  }
              }
              else {
                // add vertices with standard ids (0 .. n-1)
                for (int i = 0; i < n; i++) {
                    G.addVertex(new Vert(i));
                }
              }
              // read edges with weight
              if (weighted) {
                  for (int i = 1; i <= m; i++) {
                      aRow = br.readLine();
                      int sepIndex1 = aRow.indexOf(' ');
                      int sepIndex2 = aRow.indexOf(' ', sepIndex1+1);
                      String vStr = aRow.substring(0, sepIndex1);
                      String uStr = aRow.substring(sepIndex1+ 1, sepIndex2);
                      String wStr = aRow.substring(sepIndex2+ 1, aRow.length());
                      int vId = new Integer(vStr);
                      int uId = new Integer(uStr);
                      int w = new Integer(wStr);

                      Vert v = G.getVertex(vId);
                      Vert u = G.getVertex(uId);

                     G.addEdge(new Edge<Vert>(v,u,w));
                  }
              }
              else { // read edges without weight; 
                  for (int i = 1; i <= m; i++) {
                      aRow = br.readLine();
                      int sepIndex1 = aRow.indexOf(' ');
                      String vStr = aRow.substring(0, sepIndex1);
                      String uStr = aRow.substring(sepIndex1+ 1, aRow.length());
                      int vId = new Integer(vStr);
                      int uId = new Integer(uStr);

                      Vert v = G.getVertex(vId);
                      Vert u = G.getVertex(uId);

                     G.addEdge(new Edge<Vert>(v,u));
                  }  
              }
            fis.close();
          }
          catch (Exception e) {
                System.out.println("Reading was not successful");
                System.out.println(e.getMessage());
          } 

        return G;   

    }
}

我总是得到一个“字符串索引超出范围 3”的异常。我不知道为什么。

该文件具有以下格式: 1. row:顶点数(n) 2. row:边数(m) 顶点的id和顶点的名称用空格分隔。随后的 m 行:边的起点和终点以及边的权重(仅当 weighted = true 时)由空格分隔。
如果图形是有向的,则参数“directed”为真。如果是定向的:“dat”中的每条边 e = (a,b) 仅添加到变量 a 的邻接表中。如果它不是有向的:每条边 e = (a,b) 被添加到变量 a 的邻接表和变量 b 的邻接表中。如果顶点的 id 介于 0 和 n-1 之间且没有名称,则参数“standardIds”为真。如果边缘被加权,则参数“weighted”为真。

Graph-txt 的内容如下所示:

9
11
0 1
0 4
1 2
2 5
5 3
3 2
3 0
3 4
6 3
7 6
8 7
9

知道如何解决这个问题吗?谢谢 !

标签: javadepth-first-searchindexoutofrangeexception

解决方案


错误发生在这一行

String uStr = aRow.substring(sepIndex1+ 1, sepIndex2);

原因是因为文件中的一行中只有(最多)2个数字,因此以下只有一个空格将设置sepIndex2为-1,因为sepIndex1是1

int sepIndex2 = aRow.indexOf(' ', sepIndex1+1);

为了清楚起见,这是我在测试时使用的。

输入文件的最终版本

9
2
0 1
0 4
1 2
2 5
5 3
3 2
3 0
3 4
6 3
7 6
8 7

还有我的代码版本,其中我删除了对未知类的任何引用,例如Graphetc 以及其他一些编辑。这样做是因为我只对有关读取文件的逻辑感兴趣

public static void main(String[] args) {
    GraphRead.FileToGraph("~/temp/graf.txt", true, false, false);
}

public static void FileToGraph(String dat, boolean directed, boolean standardIds, boolean weighted) {
    FileInputStream fis = null;
    try {
        fis = new FileInputStream(dat);
    } catch (Exception e) {
        System.out.println(dat + " couldn't be opened");
        System.out.println(e.getMessage());
    }
    try {
        InputStreamReader isr = new InputStreamReader(fis);
        BufferedReader br = new BufferedReader(isr);

        // read number of vertices
        String aRow;
        aRow = br.readLine();
        int n = new Integer(aRow);

        // read number of edges
        aRow = br.readLine();
        int m = new Integer(aRow);

        if (!standardIds) { // vertices have arbitrary ids and get a name
            // read vertices (1. substring: id, 2. substring: name)
            System.out.println("!standardIds");
            for (int i = 1; i <= n; i++) {
                aRow = br.readLine();
                int sepIndex1 = aRow.indexOf(' ');
                String vId = aRow.substring(0, sepIndex1);
                String vStr = aRow.substring(sepIndex1 + 1, aRow.length());
                int id = new Integer(vId);
                System.out.println(vId + ":" + vStr);
            }
        }

        // read edges with weight
        if (weighted) {
            System.out.println("weighted");
            for (int i = 1; i <= m; i++) {
                aRow = br.readLine();
                int sepIndex1 = aRow.indexOf(' ');
                int sepIndex2 = aRow.indexOf(' ', sepIndex1 + 1);
                String vStr = aRow.substring(0, sepIndex1);
                String uStr = aRow.substring(sepIndex1 + 1, sepIndex2);
                String wStr = aRow.substring(sepIndex2 + 1, aRow.length());
                System.out.println(uStr + ":" + wStr);
            }
        } else { // read edges without weight;
            System.out.println("!weighted");
            for (int i = 1; i <= m; i++) {
                aRow = br.readLine();
                int sepIndex1 = aRow.indexOf(' ');
                String vStr = aRow.substring(0, sepIndex1);
                String uStr = aRow.substring(sepIndex1 + 1, aRow.length());
                System.out.println(vStr + ":" + uStr);
            }
        }
        fis.close();
    } catch (Exception e) {
        System.out.println("Reading was not successful");
        System.out.println(e.getMessage());
    }
}

推荐阅读