简体   繁体   中英

java, how to read a .txt file that have multiple lines of different numbers of integers

I have a .txt file, each line is in the format like this

1 2,10 3,20

2 6,87
. . .

This file actually represents a graph, line 1 says that Vertex 1 have directed edge to vertex 2 and the length is 10, vertex 1 also have directed edge to vertex 3 and the length is 20. Line 2 says that Vertex 2 only have one directed edge to vertex 6, and the length is 87.

I want to do Dajkstra's shortest path algorithm. I don't want to define vertex class, edge class, etc., rather, I want to store each line into a 2-d array, so that by using index, I can get the graph info. If it were in python, I would store the whole file into a nested list [[(2,10) (3,20)], [(6,87)], ...], so that without making vertex, edge class, I can easily access all necessary graph info by indexing the list.

My question is, how to do this in Java? 2-D array not good because each line might have different number of integers. ArrayList might be good, but how to read the whole txt file into such arraylist efficently?

    ArrayList<ArrayList<Integer>> graph = new ArrayList<ArrayList<Integer>>(); 

    try{

            Scanner sc = new Scanner(new File("a.txt"));               
            while(sc.hasNextLine()){
            String line= sc.nextLine();             
            ArrayList<Integer> vertex = new ArrayList<Integer>();               
            Scanner lineContents = new Scanner(line).useDelimiter("\\D"); //"\\D" means any none digit

            while (lineContents.hasNext()) {
                    vertex.add(lineContents.nextInt());
            }

            graph.add(vertex);
            lineContents.close();
        }
        sc.close();
    }

try this method:

public Map<Integer, Map<Integer, Integer>> process(String filePath) throws IOException {
    Map<Integer, Map<Integer, Integer>> graph = new HashMap<>();

    Files.lines(new File(filePath).toPath())
            .map(line -> line.split(" "))
            .map(Arrays::asList)
            .forEachOrdered(elements -> {
                int vertexId = parseInt(elements.get(0));

                Map<Integer, Integer> vertexMap = new HashMap<>();
                elements.subList(1, elements.size()).stream()
                        .map(element -> element.split(","))
                        .map(Arrays::asList)
                        .forEach(pair -> vertexMap.put(parseInt(pair.get(0)), parseInt(pair.get(1))));

                graph.put(vertexId, vertexMap);
            });


    return graph;
}

I returned a Map instead of List because working by index is a bad practice and you get the same functionality.

Also note this is not tested - it might not work but I think it will.

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