地铁最短路径的代码部分

讲一下自己的思路,因为是无权路径,所以我用BFS来求最短路径,得到最短路径后,两点确定一条线路,来判断换乘信息。

类说明

职责
Line 存放线路信息
Station 存放站点信息
TestClass 代码主体部分,信息读取和最短路径都在里面实现

 

 这是Line类的代码

package subway;

import java.util.ArrayList;

public class Line {
    private String line_name; //存放线路名称
    private ArrayList<String> stations =new  ArrayList<>();  //存放站点名称
    
    public String getLine_name() {
        return line_name;
    }
    public void setLine_name(String line_name) {
        this.line_name = line_name;
    }
    public ArrayList<String> getStations() {
        return stations;
    }
    public void setStations(ArrayList<String> stations) {
        stations = stations;
    }
    public void addStation(String station) {
        stations.add(station);
    }
    
}

 

这是Station类的代码

public class Station {
    
    private String Station_name;  //存放站点名
    private ArrayList<String> Line = new ArrayList<String>();   //存放站点所在的线路
    private ArrayList<Station> Linkstation = new ArrayList<Station>();  //存放相邻的站点
    public int dist;  
    public Station pre;  //存放最短路径的前驱节点

   public ArrayList<Station> getLinkstation() { return Linkstation; } public void setLinkstation(ArrayList<Station> linkstation) { Linkstation = linkstation; } public void addLinkstation(Station station) { Linkstation.add(station); } public String getStation_name() { return Station_name; } public void setStation_name(String station_name) { Station_name = station_name; } public void addLine(String line) { Line.add(line); } public ArrayList<String> getLine() { return Line; } public void setLine(ArrayList<String> line) { Line = line; } }

求最短路径的代码,因为是无权路径,就用BFS来求了

    public static void shortestPath(Station station){
        Queue<Station> queue = new LinkedList<>();
        station.dist=0;
        queue.offer(station);
        
        while(!queue.isEmpty()) {
            Station vertex=queue.poll();
            for(Station linkstation:vertex.getLinkstation()) {
                if(linkstation.dist==MaxValue) {
                    linkstation.dist=vertex.dist+1;
                    queue.offer(linkstation);
                    linkstation.pre=vertex;
                }
            }
        }
    }

取得最短线路的代码

通过递归来获得最短线路

    public static void showPath(Station end_station,ArrayList<Station> result) {
        if(end_station.pre!=null)  
            showPath(end_station.pre,result);
        result.add(end_station);
    }

判断换乘的代码

        String changeLine=getSameLine(shortestPath.get(0),shortestPath.get(1));
        for(int i=0;i<shortestPath.size();i++) {
            if(i>=2) {
                if(!getSameLine(shortestPath.get(i),shortestPath.get(i-1)).equals(changeLine)) {
                    changeLine=getSameLine(shortestPath.get(i),shortestPath.get(i-1));
                    System.out.println("------->换乘"+changeLine);
                }
            }
            System.out.println(shortestPath.get(i).getStation_name());
        }
       }

主要思路就是先判断前两个站点的线路,存储在changeLine里,然后从第三个站点开始,循环判断第i-1个站点,到第i个站点的连线是不是和changeLine一样,如果不一样就输出换乘信息,并且更新changeLine。

 

全部代码:

package subway;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;


public class TestClass {
    static final int MaxValue=65535;
    static final int MaxNum=400;
    
    public static void main(String[] args) {
        System.out.print("请输入地铁文件路径:");
        Scanner input=new Scanner(System.in);
        File file = new File(input.nextLine());
        ArrayList<Station> stations= new ArrayList<>();
        ArrayList<Line> lines = new ArrayList<Line>();
        try{
                BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
                String s = null;
                int j;
                Station last_station= new Station(); //连接相邻的两个车站
                while ((s = br.readLine()) != null) {
                    String tokens[]=s.split(" ");
                    Line line = new Line();
                    line.setLine_name(tokens[0]);
                    for(int i=1;i<tokens.length;i++) {
                        line.addStation(tokens[i]);
                        for(j=0;j<stations.size();j++) {
                            if(stations.get(j).getStation_name().equals(tokens[i])) //先去stations判断车站是否存在
                                {
                                    stations.get(j).addLine(tokens[0]);
                                    if(i!=1) {
                                        stations.get(j).addLinkstation(last_station); //因为读取的是线路,也就说前后两个车站是相连的,通过last_station连接车站
                                        last_station.addLinkstation(stations.get(j));  //别忘记了last_station也要连接当前的station
                                    }
                                    last_station=stations.get(j);
                                    break;
                                }
                        }
                        if(j==stations.size()) {
                            Station station = new Station();
                            station.addLine(tokens[0]);
                            station.setStation_name(tokens[i]);
                            station.dist=MaxValue;
                            if(i!=1) {
                                station.addLinkstation(last_station);
                                last_station.addLinkstation(station);
                            }
                            stations.add(station);
                            last_station=station;
                        }
                    
                    }
                    lines.add(line);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        System.out.print("输入数字选择功能: 1.查询最短路径 2.查询线路站点 ");  //功能选择
        int number=input.nextInt();
        if(number==1){
        System.out.print("请输入起始站:");
        String begin_station_name=input.next();
        System.out.print("请输入终点站:");
        String end_station_name=input.next();
        Station end_station = new Station();
        Station begin_station = new Station();
        for(Station station:stations) {
            if(station.getStation_name().equals(begin_station_name)) {
                begin_station=station;
                shortestPath(station);
            }
            if(station.getStation_name().equals(end_station_name))
                end_station=station;
        }
        ArrayList<Station> shortestPath=new ArrayList<Station>();
        showPath(end_station,shortestPath);
        String changeLine=getSameLine(shortestPath.get(0),shortestPath.get(1));
        for(int i=0;i<shortestPath.size();i++) {
            if(i>=2) {
                if(!getSameLine(shortestPath.get(i),shortestPath.get(i-1)).equals(changeLine)) {
                    changeLine=getSameLine(shortestPath.get(i),shortestPath.get(i-1));
                    System.out.println("------->换乘"+changeLine);
                }
            }
            System.out.println(shortestPath.get(i).getStation_name());
        }
        }
        else if(number==2) {
            System.out.print("请输入线路名称:");
            String line_name=input.next();
            int flag=1;
            for(Line line:lines) {
                if(line.getLine_name().equals(line_name))
                    {
                        System.out.print(line.getStations().toString());
                        flag=0;
                        break;
                    }
            }
            if(flag==1) {
                System.out.print("线路名输入有误");
            }
        }
        else {
            System.out.print("输入有误,请重试");
        }
       }
    public static void shortestPath(Station station){
        Queue<Station> queue = new LinkedList<>();
        station.dist=0;
        queue.offer(station);
        
        while(!queue.isEmpty()) {
            Station vertex=queue.poll();
            for(Station linkstation:vertex.getLinkstation()) {
                if(linkstation.dist==MaxValue) {
                    linkstation.dist=vertex.dist+1;
                    queue.offer(linkstation);
                    linkstation.pre=vertex;
                }
            }
        }
    }
    public static void showPath(Station end_station,ArrayList<Station> result) {
        if(end_station.pre!=null)  
            showPath(end_station.pre,result);
        result.add(end_station);
    }
    private static String getSameLine(Station station1,Station station2) {  
        for(String line1:station1.getLine()) {
            for(String line2:station2.getLine()) {
                if(line1.equals(line2))
                    return line1;
            }
        }
        return null;
    }
    

}

 

 

 

测试用例:

1.单线站点-单线站点

2.换乘站-换乘站

 

 

 3.输入错误的站点

 

 

 

4.查询线路

 

 

 总结

1.第一次用博客来写记录自己写的代码,感觉还是挺奇妙的,希望这种方式能更好的促进自己的学习。

2.因为用的是BFS算法,所以只能得到一条最短路径,如果有多条最短路径,应该使用dijkstra算法更好。

posted @ 2020-11-02 20:56  suppersam  阅读(359)  评论(0编辑  收藏  举报