简体   繁体   中英

Java: how to parse a file to get edges for generating graph

I'm having trouble reading data from file. Currently I'm adding edges inside the program, which generates a graph based on lists of edges. However, I want my program to read edges from a file to create a graph (read a.txt file line by line)

The.txt file would look something like this:

0, 1
0, 4
1, 2
1, 3
1, 4
2, 3
3, 4

The sample code for the program looks like this:

import java.util.*; 

class GraphIO { 

    static void addEdge(ArrayList<ArrayList<Integer> > adj, 
                        int u, int v) 
    { 
        adj.get(u).add(v); 
        adj.get(v).add(u); 
    } 

    static void printGraph(ArrayList<ArrayList<Integer> > adj) 
    { 
        for (int i = 0; i < adj.size(); i++) { 
            System.out.println("\nAdjacency list of vertex" + i); 
            for (int j = 0; j < adj.get(i).size(); j++) { 
                System.out.print(" -> "+adj.get(i).get(j)); 
            } 
            System.out.println(); 
        } 
    } 

    public static void main(String[] args) 
    { 
        int V = 5;
        ArrayList<ArrayList<Integer> > adj  
                    = new ArrayList<ArrayList<Integer> >(V); 

        for (int i = 0; i < V; i++) 
            adj.add(new ArrayList<Integer>()); 

        addEdge(adj, 0, 1); 
        addEdge(adj, 0, 4); 
        addEdge(adj, 1, 2); 
        addEdge(adj, 1, 3); 
        addEdge(adj, 1, 4); 
        addEdge(adj, 2, 3); 
        addEdge(adj, 3, 4); 

        printGraph(adj); 
    } 
} 

Does anyone have a suggestion?

EDIT: I added a List this time and called addEdge correctly this time. Sorry I ignored the method signature last time.

In your while loop, when you read a new line, you can add an edge right there, after the parsing the numbers from the read line:

while (reader.hasNextLine()) {
    String[] nums = reader.nextLine().split(", ");
    addEdge(adj, Integer.parseInt(nums[0]), Integer.parseInt(nums[1]));
}

You also need a catch after your try.

Side note: I don't think you should be skipping a line, but I don't know if that's a specific thing your program is supposed to do.

Your addEdge method should look like this to make sure your List is all filled up with ArrayList s and you don't get an IndexOutOfBoundsException .

static void addEdge(List<List<Integer>> adj, int u, int v) {
  int bigger = (u > v ? u : v) + 1;
  //Keep increasing the size until it's right
  while (adj.size() < bigger) adj.add(new ArrayList<>());
  adj.get(u).add(v);
  adj.get(v).add(u);
}

And your main method would have to be changed slightly. Since you don't know the number of vertices, you just make an empty ArrayList of default capacity. Declaring adj as List<List<Integer>> is not necessary - you can still use ArrayList , but List is an interface that other classes implement, and it's not absolutely necessary to use ArrayList s here, so I used that.

I also removed the reader.nextLine() because you're discarding that data, and that edge doesn't get registered.

  List<List<Integer>> adj = new ArrayList<>();

  File input = new File("filename"); //Define the input file with "filename"
  try {
   Scanner reader = new Scanner(input); //read in the file

   while (reader.hasNextLine()) {
    String[] nums = reader.nextLine().split(", ");
    addEdge(adj, Integer.parseInt(nums[0]), Integer.parseInt(nums[1]));
   }
   printGraph(adj);
   reader.close();
  } catch (IOException e) {
   throw new RuntimeException(e);
  }

Output:

Adjacency list of vertex0
 -> 1 -> 4

Adjacency list of vertex1
 -> 0 -> 2 -> 3 -> 4

Adjacency list of vertex2
 -> 1 -> 3

Adjacency list of vertex3
 -> 1 -> 2 -> 4

Adjacency list of vertex4
 -> 0 -> 1 -> 3

However, this program is very dependent on the order of the edges in the txt file, so I would rather do it like this. It's not very efficient, it uses Maps and Sets instead of ArrayLists, but it feels clearer to me.

static void addEdge(Map<Integer, Set<Integer>> adj, int u, int v) {
  //If it doesn't already exist, add the set of adjacent vertices here
  if (!adj.containsKey(u)) adj.put(u, new HashSet());
  if (!adj.containsKey(v)) adj.put(v, new HashSet());

  adj.get(u).add(v);
  adj.get(v).add(u);
 }

 static void printGraph(Map<Integer, Set<Integer>> adj) {
  for (int u : adj.keySet()) {
   System.out.println("\nAdjacency list of vertex" + u);
   for (int v : adj.get(u)) {
    System.out.print(" -> " + v);
   }
   System.out.println();
  }
 }

 public static void main(String[] args) {
  Map<Integer, Set<Integer>> adj = new HashMap<>();

  File input = new File("filename");
  try {
   Scanner reader = new Scanner(input); //read in the file

   while (reader.hasNextLine()) {
    String[] nums = reader.nextLine().split(", ");
    addEdge(adj, Integer.parseInt(nums[0]), Integer.parseInt(nums[1]));
   }
   printGraph(adj);
   reader.close();
  } catch (IOException e) {
   throw new RuntimeException(e);
  }
 }

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