0

I have to create a weighted graph from a text file. Below is a example how the text file looks like. The first number is the id of the actual train station. The second number is a possible destination and after the comma is the time in seconds, it takes to travel. The the third number is another possible destination.

060060101832 060063101842,78 060054104822,90
060054104822 060060101832,90 060057104812,90 060058101502,90 060054105611,66
060057104812 060054104822,90 060057102802,72 

I want to store the routes in an ArrayList. Each route object should look like this:

Start: 060060101832 
Destination: 060063101842
Time: 78

The problem is, I have to store multiple routes for the same starting location. How do I read the lines properly in, using a scanner? My approach was this:

while (routes.hasNext()) {
        routes.useDelimiter(",| |\\n");
        String start = routes.next();
        String dest= routes.next();
        String time= routes.next();
        Edge edge = new Edge(start, dest, time);
        edges.add(edge);
    }

Since I cannot go back in the text file, I can't imagine how a right solution should look like.

Ray Ban
  • 67
  • 7

1 Answers1

2

This is not a complete code nor it was tested. It may or may not work but it will guide you anyways.

// Java 8
Node n;
Edge e;
String[] splittedLine;
String[] splittedEdge;
HashMap<String, Node> stationNumberToNode = new HashMap<>();
// if the file is not too large, you can read the file at once
List<String> lines = Files.readAllLines(new File("path/to/file.txt").getPath());
for(String line : lines){
  splittedLine = line.split(" ");
  if((n = stationNumberToNode.get(splittedLine[0]) == null){
    n = new Node(splittedLine[0]); // assuming your Node has a constructor that takes the station id
    stationNumberToNode.put(stationNumberToNode[0], n);
  }
  for(int i = 1; i < splittedLine.lenght; ++i){
    splittedEdge = splittedLine[i].split(",");
    e = new Edge(splittedEdge[0], splittedEdge[1]); // assuming your Edgehas a constructor that takes the destination station and the cost
    n.addEdge(e);
  }
}

Explanation

Node n;
Edge e;
String[] splittedLine;
String[] splittedEdge;
HashMap<String, Node> stationNumberToNode = new HashMap<>();

Ideally you should always declare variables outside loops, so you avoid allocating a new memory on every iteration. Thus, we declare our 5 variables before entering the loop. The HashMap is used here to cover the case that your input is not always grouped and you avoid having to perform a list search everytime.

List<String> lines = Files.readAllLines(new File("path/to/file.txt").getPath());

Read all the lines on the file at once. Alternatively, as requested on the question, you can read the file using Scanner like on this anwer. You have to change the way you iterate over the lines, though.

splittedLine = line.split(" ");

Splits the line on the " ", since your input file is well formated.

if((n = stationNumberToNode.get(splittedLine[0]) == null){
  n = new Node(splittedLine[0]); // assuming your Node has a constructor that takes the station id
  stationNumberToNode.put(stationNumberToNode[0], n);
}

Checks if the current node is already on the HashMap. If yes, it will be stored in the variable n. Else, it will create a Node with the current id and add it to our HashMap.

for(int i = 1; i < splittedLine.lenght; ++i){
  splittedEdge = splittedLine[i].split(",");
  e = new Edge(splittedEdge[0], splittedEdge[1]); // assuming your Edgehas a constructor that takes the destination station and the cost
  n.addEdge(e);
}

Since everything in the input file is the destination station and its cost (id,cost), we iterate on the splittedLine from index 1 onwards. For every edge data, we split based on "," (from your input file), whereas splittedEdge[0] will be the destination id and splittedEdge[1] will be the cost to that destination. We create an Edge with that information and add that Edge to the Node object.

luizfzs
  • 1,146
  • 1
  • 18
  • 32