北京地铁项目

github:https://github.com/leo-xlz/Subway-beijing

在这里插入图片描述

模块分析-----

zucc.edu.cn.model

存放站点信息和路径信息
station.java

    private String name;//站点名字

    private String line;//所属路线

    private List<Station> linkStations = new ArrayList<>();//相邻连接站点

routine.java

  private Station star;//起点
    private Station end;//终点
    private int distance;
    private List<Station> path=new ArrayList<>();

main 调用函数并且运行

main.java

   public static void main(String[] args) throws UnsupportedEncodingException {
        switch (args[0]) {
            //读入subway.txt文件数据
            case "-map":
                //-map subway.txt
                if (args.length == 2) {
                    FileOperate.Readfile = System.getProperty("user.dir") + File.separator + args[1];
                    //根据路径,读取地铁信息,并打印。
                    FileOperate.getFile();
                    System.out.println("成功读取subway.txt文件");
                } else {
                    System.out.println("验证参数格式!");
                }
                break;
            //查询指定线路的文件数据,并写入到station.txt文件中
            case "-a":
                //-a 1号线 -map subway.txt -o station.txt

                if (args.length == 6) {
                    FileOperate.Readfile = System.getProperty("user.dir") + File.separator + args[3];
                    FileOperate.Writefile = System.getProperty("user.dir") + File.separator + args[5];

                    FileOperate.getFile();
                    System.out.println(args[1]);
                    if (FileOperate.Map.keySet().contains(args[1])) {
                        FileOperate.loadLine(args[1]);
                        System.out.println("已将地铁" + args[1] + "的各站点信息写入station.txt文件");
                    } else {
                        System.out.println("线路不存在");
                    }
                } else {

                    System.out.println("验证参数格式!");
                }
                break;
            //查询指定站点之间的最短路径信息
            case "-b":
                //-b 天安门西 北京大学东门 -map subway.txt -o routine.txt
                System.out.println(1);
                if (args.length == 7) {
                    FileOperate.Readfile = System.getProperty("user.dir") + File.separator + args[4];
                    FileOperate.Writefile = System.getProperty("user.dir") + File.separator + args[6];
                    FileOperate.getFile();
                    FileOperate.shorestPath(args[1],args[2]);
                    System.out.println("已将" + args[1] + "到" + args[2] + "最短路径的结果写入routine. txt文件");

                } else {
                    System.out.println("验证参数格式!");
                }
                break;
            default:
                System.out.println("验证参数格式!");
        }
    }

zucc.edu.cn.manager

Dijkstra.java 最短路径算法

  public static HashMap<Station, Routine> resultMap = new HashMap<>();//结果集
    public static List<Station> list = new ArrayList<>();//分析过的站点


    public static Routine dijkstra(Station star, Station end) {

        if (!list.contains(star))
            list.add(star);
        if (star.equals(end)) {//如果起始点和终点相同,直接返回
            Routine result = new Routine();

            result.setDistance(0);
            result.setEnd(star);
            result.setStar(star);
            resultMap.put(star, result);
            return resultMap.get(star);··
        }
        if (resultMap.isEmpty()) {
            List<Station> linkedStation = getLinkStations(star);
            for (Station station : linkedStation) {
                Routine routine = new Routine();
                routine.setStar(star);
                routine.setEnd(station);
                routine.setDistance(1);
                routine.getPath().add(station);
                resultMap.put(station, routine);
            }
        }
        Station next = getNextStation();
        if (next == null) {
            Routine routine = new Routine();
            routine.setDistance(0);
            routine.setStar(star);
            routine.setEnd(end);
            return resultMap.put(end, routine);
        }
        //如果得到的最佳邻接点与终点相同,则直接返回结果集
        if (next.equals(end))
            return resultMap.get(next);

        List<Station> bestlinkStation = getLinkStations(next);
        for (Station best : bestlinkStation) {
            if (list.contains(best))
                continue;
            int distance =0;

            if (next.getName().equals(best.getName()))
                distance = 0;
            distance = resultMap.get(next).getDistance() + 1;

            List<Station> nextPass = resultMap.get(next).getPath();
            Routine res = resultMap.get(best);
            if (res != null) {
                if (res.getDistance() > distance) {
                    res.setDistance(distance);
                    res.getPath().clear();
                    res.getPath().addAll(nextPass);
                    res.getPath().add(best);
                }
            } else {
                res = new Routine();
                res.setDistance(distance);
                res.setStar(star);
                res.setEnd(best);
                res.getPath().addAll(nextPass);
                res.getPath().add(best);
            }
            resultMap.put(best, res);
        }
        list.add(next);


        return dijkstra(star, end);

    }

    //通过计算最小权值 计算下一个需要分析的点
    private static Station getNextStation() {
        int min = 1000;
        Station rets = null;
        Set<Station> stations = resultMap.keySet();
        for (Station station : stations) {
            if (list.contains(station)) {
                continue;
            }
            Routine result = resultMap.get(station);
            if (result.getDistance() < min) {
                min = result.getDistance();
                rets = result.getEnd();
            }
        }
        return rets;
    }
  • FileOperate.java 文件处
    读取文件,通过 HashMap<String,List> Map来存放地铁线路信息
    public static String Readfile;
    public static String Writefile;
    public static HashMap<String,List<Station>> Map=new HashMap<>();//存放地铁线路信息
    public  static HashSet<List<Station>> lineSet=new LinkedHashSet<>();//所有线路的集合
    public static void getFile() {

        File file=new File(Readfile);


        BufferedReader rd=null;
        /* 读取数据 */
        try {
            InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream(file),"UTF-8");
            rd=new BufferedReader(inputStreamReader);
            String lineTxt = null;
            while ((lineTxt = rd.readLine()) != null) {
                String[] s = lineTxt.split(" ");//创建一个临时存放数据的数组
                List<Station>  Stations = new ArrayList<>();
                for(int i = 1;i<s.length;i++){     //将读入的站点并加入到对应线路的List中
                    Station station = new Station(s[i],s[0]);
                    Stations.add(station);
                }
                lineSet.add(Stations);
                Map.put(s[0],Stations);
            }
            rd.close();
        } catch (UnsupportedEncodingException e) {  //异常处理
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }catch (IOException e) {
            e.printStackTrace();
        } finally {
        }
        }
    public static void loadLine(String Line){ //根据指定的路线输出此路线的所有站点
        File file=new File(Writefile);
        List<Station> line;
        BufferedWriter bw = null;
        try {
            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream(file),"UTF-8");
            bw = new BufferedWriter(outputStreamWriter);
            line=Map.get(Line);
            bw.write(Line+"\n");
            bw.write("--------\n");
          	bw.write("--------\n");

            for(int i=0;i<line.size();i++)
                    bw.write(line.get(i).getName()+"\r\n");//写入指定路线的站点信息
            bw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static  String getLineName(Station station){//根据站点名称得到线路名称
        String sName=station.getName();
        for(Map.Entry<String,List<Station>>entry:Map.entrySet()){
            List<Station> stations=entry.getValue();
            for(Station s:stations){
                if(s.getName().equals(sName))
                    return entry.getKey();
            }
        }
        return  null;
    }

    public static void shorestPath(String star,String end){
        File file = new File(Writefile);
        BufferedWriter bw = null;

        try{
            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream(file),"UTF-8");
            bw = new BufferedWriter(outputStreamWriter);

            Routine routine=Dijkstra.dijkstra(new Station(star),new Station(end));

            bw.write((routine.getPath().size()+1)+"\r\n");
            String lineName=getLineName(routine.getStar());
            bw.write(lineName+"\n");
            bw.write(routine.getStar().getName()+"\n");
            for(int i=0;i<routine.getPath().size()-1;i++) {
                bw.write(routine.getPath().get(i).getName()+"\n");
                if(!routine.getPath().get(i+1).getLine().equals(routine.getPath().get(i).getLine())){
                    bw.write("---需换乘"+routine.getPath().get(i+1).getLine()+"---\n");
                }
            }
            bw.write(routine.getEnd().getName()+"\n");
            bw.close();

        }catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

遇到的问题

1.环线不知道怎么设计
2.HashMap<String,List>不知道怎么进行遍历
3.编写迪杰斯特拉算法不够熟练
4.准备工作没有做好,没有先画一张草图来预先模拟一下各个功能怎么实现,同时没有将各个存储结构的关系画出来,以至于在写代码时经常会弄混各个结构。

所做工作

1.文件的读入与输出
2.数据存储结构的编辑
3.编写迪杰斯特拉算法来输出最短路径    

测试

1.程序启动时需要通过读取 -map 参数来获得对应的自定义地铁文件(命名为 subway.txt),从而得到地铁线路图的信息。

java subway -map subway.txt

在这里插入图片描述
2.给定路线,输出此路线上所有站点,保存信息到station.txt

java subway -a 1号线 -map subway.txt -o station.txt

在这里插入图片描述
3.给出两个站点,输出两点间的最短路径,保存文件到routine.txt

subway.exe -b 香山 焦化厂 -map subway.txt -o routine.txt

在这里插入图片描述