简体   繁体   中英

Adjacency List to Directed Graph

I am working on a program that implements Dijkstra's shortest-path algorithm. It starts with the input of an adjacency list in a text file, of the format:

1 2 1 3 1
2 4 2
3 2 2 5 4
4 3 3 5 3
5 1 4

with the pattern vertexname adj.vertex weight adj.vertex weight.....

I have found some sample code that populates the graph like this:

private static final Graph.Edge[] GRAPH = {
    new Graph.Edge("a", "b", 7),
    new Graph.Edge("a", "c", 9),
    new Graph.Edge("a", "f", 14),
    new Graph.Edge("b", "c", 10),
    new Graph.Edge("b", "d", 15),
    new Graph.Edge("c", "d", 11),
    new Graph.Edge("c", "f", 2),
    new Graph.Edge("d", "e", 6),
    new Graph.Edge("e", "f", 9),};

This would work, except, as I stated, I need to populate this data from a text file formatted similar to the above one. The trouble I am running into is that there is not a set limit on the amount of data per line. A node could have one or infinitely many other nodes attached to it. I am trying to come up with a solution that is able to handle this problem. So far I have this rough attempt inside my main method:

Scanner scanner = new Scanner(new File(filename));
    while(scanner.hasNextInt()){
        String source = scanner.next();
        String to = scanner.next();
        int weight = scanner.nextInt();
        Graph.Edge edge = new Graph.Edge(source, to, weight);
        if(scanner.hasNext()){
            to = scanner.next();
            weight = scanner.nextInt();
            Graph.Edge edge2 = new Graph.Edge(source, to, weight);
        }
    }

When I try and run this program, I get NoSuchElementException at Scanner.throwfor, Scanner.next and inside my main class on this line:

String to = scanner.next();

I understand that my attempt isn't currently completely syntactically correct, but am I on the right path towards finding a solution? Also, is there anything key I am looking over or that would make this easier? Thanks!

EDIT: Here is the link to the code I started with http://rosettacode.org/wiki/Dijkstra%27s_algorithm#Java

[EDITED]

Here is a code snippet that will fill in an ArrayList with the Edges instances:

List<Graph.Edge> list = new ArrayList<Graph.Edge>();

try {
    Scanner scanner = new Scanner(new File(filepath));
    while(scanner.hasNextLine()){
        String source = scanner.findInLine(NAME);
        if (source != null) {
            while(true) {
              String to = scanner.findInLine(NAME);
              if (to == null) {
                  break;
              }
              int weight = Integer.valueOf(scanner.findInLine(WEIGHT));
              list.add(new Graph.Edge(source, to, weight));
            }
        }
        scanner.nextLine();
    }
} catch (Exception e) {
    e.printStackTrace();
}

It uses hasNextLine and findInLine to process a line at a time, to ensure that the edges with the same source value are created properly.

The NAME and WEIGHT patterns are defined by these constants:

static final Pattern NAME   = Pattern.compile("\\w+");
static final Pattern WEIGHT = Pattern.compile("\\d+");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM