从文件中读取邻接列表到多图

时间:2016-11-10 17:12:06

标签: java data-structures adjacency-list

所以我有这个邻接列表:哥伦布节点到芝加哥节点是.5距离等。

Columbus,Chicago,0.5
Columbus,Miami,2.0
Chicago,NewYork,1.5
Chicago,Boston,2.0
Chicago,StLouis,0.5
Chicago,Denver,2.5
Chicago,Seattle,3.0
Boston,NewYork,0.5
StLouis,Atlanta,1
StLouis,Dallas,1.0
Atlanta,Dallas,1.0
Atlanta,Miami,1.0
Dallas,Miami,2.0
Dallas,LosAngeles,2.5
LosAngeles,SanFrancisco,1.0
LosAngeles,LasVegas,0.5
SanFrancisco,LasVegas,1.0
SanFrancisco,Seattle,2.0
SanFrancisco,Denver,2.0
Denver,LasVegas,1.0
Denver,Seattle,2.0

我有以下方法从txt文件中读取上面的列表。这会将列表添加到多地图adj_list中,但缺少此部分:

“请注意,节点之间的每条路径只列出一次,但每条路径需要两次添加到邻接列表中。例如,该文件列出了第一行上Columbus和Chicago之间的路径这需要添加到Columbus的邻接列表中,作为芝加哥目的地的路径,并且需要将其添加到芝加哥的邻接列表中,目的地为Columbus“

    public static Map<String, List<Path>> readPathsFromFile(Scanner inFile) {
    Map<String, List<Path>> adj_list =  new TreeMap<String, List<Path>>();
    ArrayList<Path> list1 = new ArrayList<Path>();

    while (inFile.hasNext()){ // TO- DO add parts for both ways.
        String input = inFile.nextLine();
        String[] token = input.split(",");

        if(!adj_list.containsKey(token[0])){
            list1 = new ArrayList<Path>();
            Path path2 = new Path(token[1],Double.parseDouble(token[2]));   
            list1.add(path2);
            adj_list.put(token[0], list1);

        }else{
            Path path = new Path(token[1],Double.parseDouble(token[2]));    
            list1.add(path);
        }

    }

    return adj_list;
}

所以,我的问题首先是上面的方法是一个很好的方法来开始,如果它是如何修改这个方法,使它在两个方向上添加节点到我的列表,而不仅仅是顺序清单?

编辑:更清楚我想要的东西。

例如最终我会: SanFrancisco :( LasVegas:1.0),(西雅图:2.0),(丹佛:2.0)

我有那个部分,但它需要的是:

SanFrancisco :( LosAngeles:1.0),(LasVegas:1.0),(西雅图:2.0),(丹佛:2.0)

即。 LosAngeles有一个到旧金山的连接节点,但在调整列表中没有为旧金山明确列出。 谢谢!

1 个答案:

答案 0 :(得分:0)

您需要小心ArrayList<Path> list1。如果输入

Columbus,Chicago,0.5
Chicago,NewYork,1.5
Columbus,Miami,2.0

你会得到一张

的地图
Columbus (Chicago,0.5)
Chicago (NewYork,1.5),(Miami,2.0)

因为在读取第3行时,list1数组是芝加哥数组(在第2行中创建)。您的token[0]已知(是的,由于第1行,地图中已存在哥伦布条目),因此您直接向(Miame,2.0)添加list1距离 - 芝加哥列表。

下面的代码解决了上述问题和你在while循环之外删除列表所说的问题,而是每次都从地图中获取正确的列表。

public static Map<String, List<Path>> readPathsFromFile(Scanner inFile) {
  Map<String, List<Path>> adj_list =  new TreeMap<String, List<Path>>();

  // You do not need a list here
  // ArrayList<Path> list1 = new ArrayList<Path>();

  while (inFile.hasNext()){ // TO- DO add parts for both ways.
    String input = inFile.nextLine();
    String[] token = input.split(",");

    // 1.) Take care of 0 -> 1
    // Try and fetch the list from your treemap saved under 0
    List<Path> token0List = adj_list.get(token[0]);

    // If there was no list previously saved, you have a null value now
    if(token0List == null){

        // since there was no list previously saved,
        // create a new (empty) one and save it in the tree
        token0List = new ArrayList<Path>();
        adj_list.put(token[0], token0List );

    }

    // At this point of time, you can be sure that the token0List
    // exists and is saved correctly in the tree.

    // now you only need to add the 0 -> 1 path to the list
    // and you are done with this part of the saving.
     Path path = new Path(token[1],Double.parseDouble(token[2]));    
    token0List .add(path); // finish 0 -> 1


    // 2.) Take care of 1 -> 0
    // same procedure as 0 -> 1, only that you are swapping 
    // token[0] and token[1]
    List<Path> token1List = adj_list.get(token[1]);
    if(token1List == null){
        token1List = new ArrayList<Path>();
        adj_list.put(token[1], token1List );

    }
     Path path2 = new Path(token[0],Double.parseDouble(token[2]));    
    token1List .add(path2); // finish 1 -> 0



  }

  return adj_list;
}