北京地铁项目


GitHub地址
https://github.com/31701041/subway

 

设计思路与模块分析

Station.java
定义了站点Station的类结构和图的结构

public class Station {

    private String name; //地铁站名称

    public Station prev; //前一个站

    public Station next; //后一个站

    //本站到某一个目标站(key)所经过的所有站集合(value),保持前后顺序
    private Map> orderSetMap = new HashMap>();

    public Station (String name){
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public LinkedHashSet getAllPassedStations(Station station) {
        if(orderSetMap.get(station) == null){
            LinkedHashSet set = new LinkedHashSet();
            set.add(this);
            orderSetMap.put(station, set);
        }
        return orderSetMap.get(station);
    }

    public Map> getOrderSetMap() {
        return orderSetMap;
    }

    @Override
    public boolean equals(Object obj) {
        if(this == obj){
            return true;
        } else if(obj instanceof Station){
            Station s = (Station) obj;
            if(s.getName().equals(this.getName())){
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    @Override
    public int hashCode() {
        return this.getName().hashCode();
    }
}

 

 DataBuilder.java
读取文件,创建地铁路线(得到的是去除了第一列后的站点的集合以及总的站点的数量
得到的站点信息以HashSet> lineSet的形式保存, 每一个list保存的是其中一条线路的信息

public class DataBuilder {

public static HashSet> lineSet = new HashSet>();//所有线集合
public static int totalStaion = 0;//总的站点数量

//读取文件
public static void readFile() throws IOException{
FileInputStream inputStream = new FileInputStream("D:\\Work\\北京地铁\\src\\station.txt");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));

String str = null;
while((str = bufferedReader.readLine()) != null)
{
List line = new ArrayList();
String[] lineInformations = str.split(" ");
for(String s : lineInformations){
line.add(new Station(s));
}
line.remove(0);
for(int i =0;i){
if(i){
line.get(i).next = line.get(i+1);
line.get(i+1).prev = line.get(i);
}
}
lineSet.add(line);
totalStaion+=line.size();

}
inputStream.close();
bufferedReader.close();
}

}

 

StationIncludeLineName.java

读取文件,创建地铁路线(得到的是没有去除了第一列后的set

public class StationIncludeLineName {

public static HashSet> lineSet = new HashSet>();//所有线集合
public static int totalStaion = 0;//总的站点数量

//读取文件
public static void readFile(String fileName) throws IOException{
FileInputStream inputStream = new FileInputStream(fileName);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));

String str = null;
while((str = bufferedReader.readLine()) != null)
{
List line = new ArrayList();
String[] lineInformations = str.split(" ");
for(String s : lineInformations){
line.add(new Station(s));
}
for(int i =0;i){
if(i){
line.get(i).next = line.get(i+1);
line.get(i+1).prev = line.get(i);
}
}
lineSet.add(line);
totalStaion+=line.size();

}
inputStream.close();
bufferedReader.close();
}

}

 

Subway.java

public class Subway {

    private List outList = new ArrayList();//记录已经分析过的站点
    String allStations = "";

    //计算从s1站到s2站的最短经过路径, 并输出文件
    public String calculate(Station s1, Station s2) {

        //长度相等级找完了全部的路径,输出文件
        if (outList.size() == DataBuilder.totalStaion) {

            allStations+="找到目标站点:" + s2.getName() + ",共经过" + (s1.getAllPassedStations(s2).size() - 1) + "站"+"\n";

            for (Station station : s1.getAllPassedStations(s2)) {

                allStations+=station.getName() + "->";
            }
            return allStations;
        }
        if (!outList.contains(s1)) {
            outList.add(s1);
        }
        //如果起点站的OrderSetMap为空,则第一次用起点站的前后站点初始化之
        if (s1.getOrderSetMap().isEmpty()) {
            List Linkedstations = getAllLinkedStations(s1);
            for (Station s : Linkedstations) {
                s1.getAllPassedStations(s).add(s);
            }
        }
        Station parent = getShortestPath(s1);//获取距离起点站s1最近的一个站(有多个的话,随意取一个)
        if (parent == s2) {

            allStations+="找到目标站点:" + s2 + ",共经过" + (s1.getAllPassedStations(s2).size() - 1) + "站"+"\n";
            for (Station station : s1.getAllPassedStations(s2)) {
                
                allStations+=station.getName() + "->";
            }
            return allStations;
        }
        for (Station child : getAllLinkedStations(parent)) {
            if (outList.contains(child)) {
                continue;
            }
            int shortestPath = (s1.getAllPassedStations(parent).size() - 1) + 1;//前面这个1表示计算路径需要去除自身站点,后面这个1表示增加了1站距离
            if (s1.getAllPassedStations(child).contains(child)) {
                //如果s1已经计算过到此child的经过距离,那么比较出最小的距离
                if ((s1.getAllPassedStations(child).size() - 1) > shortestPath) {
                    //重置S1到周围各站的最小路径
                    s1.getAllPassedStations(child).clear();
                    s1.getAllPassedStations(child).addAll(s1.getAllPassedStations(parent));
                    s1.getAllPassedStations(child).add(child);
                }
            } else {
                //如果s1还没有计算过到此child的经过距离
                s1.getAllPassedStations(child).addAll(s1.getAllPassedStations(parent));
                s1.getAllPassedStations(child).add(child);
            }
        }
        outList.add(parent);
        calculate(s1, s2);//重复计算,往外面站点扩展
        return allStations;
    }

    //取参数station到各个站的最短距离,相隔1站,距离为1,依次类推
    private Station getShortestPath(Station station) {
        int minPatn = Integer.MAX_VALUE;
        Station rets = null;
        for (Station s : station.getOrderSetMap().keySet()) {
            if (outList.contains(s)) {
                continue;
            }
            LinkedHashSet set = station.getAllPassedStations(s);//参数station到s所经过的所有站点的集合
            if (set.size() < minPatn) {
                minPatn = set.size();
                rets = s;
            }
        }
        return rets;
    }

    //获取参数station直接相连的所有站,包括交叉线上面的站
    private List getAllLinkedStations(Station station) {
        List linkedStaions = new ArrayList();
        for (List line : DataBuilder.lineSet) {
            if (line.contains(station)) {//如果某一条线包含了此站
                Station s = line.get(line.indexOf(station));
                if (s.prev != null) {
                    linkedStaions.add(s.prev);
                }
                if (s.next != null) {
                    linkedStaions.add(s.next);
                }
            }
        }
        return linkedStaions;
    }

    //文件写入
    public static void writeFileString(String strings, String writeFileName) {
        File fileDir = new File(writeFileName);
        if(!fileDir.isFile()){
            try {
                fileDir.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        try {
            FileWriter fw = new FileWriter(fileDir);
            fw.write(strings);
            fw.flush();
            fw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws IOException {
        String map = "-map \\S+ ";
        String line = "-a \\S+ -map \\S+ -o \\S+ ";
        String path = "-b \\S+ \\S+ -map \\S+ -o \\S+ ";

        String arge = "";

        for (String i : args) {
            arge += i + " ";
        }

        if (arge.matches(map)) {
            String readFile = args[1];
            StationIncludeLineName.readFile(readFile);
            for (List linename : StationIncludeLineName.lineSet) {
                for (int i = 0; i < linename.size(); i++) {
                    System.out.print(linename.get(i).getName() + "-->");
                }
                System.out.println();

            }
        } else if (arge.matches(line)) {
            String lineName = args[1];
            String readFile = args[3];
            String writeFile = args[5];
            StationIncludeLineName.readFile(readFile);
            Station station = new Station(lineName);
            String allStations = "";
            int flag = 0;//判断是否存在该路线
            for (List linename : StationIncludeLineName.lineSet) {
                if (linename.contains(station)) {
                    allStations+=linename.get(0).getName() + "包括的站点:"+"\n";
                    for (int i = 1; i < linename.size(); i++) {
                        allStations+=linename.get(i).getName() + "-->";
                    }
                    flag=1;
                }
            }
            if(flag==0){
                System.out.println("该路线不存在");

            }
            else{
                writeFileString(allStations, writeFile);
            }

        } else if (arge.matches(path)) {
            String start = args[1];
            String end = args[2];
            String readFile = args[4];
            String writeFile = args[6];
            DataBuilder.readFile(readFile);
            Subway sw = new Subway();
            String allStations = sw.calculate(new Station(start), new Station(end));
            writeFileString(allStations, writeFile);
        }else{
            System.out.println("输入参数有误");
        }
    }
}

 

 

测试

 

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

java subway -map subway.txt

北京地铁项目_第1张图片

 

 

 需求2
在给定地铁线路时,你的程序就需要能够从线路的起始站点开始,依次输出该地铁线经过的所有站点,直到终点站

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

 

 

 需求3
给出起点和终点, 保存路径信息到文件中

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

 

 

 



 输入参数有误

 

 

 

路线不存在的情况

 

你可能感兴趣的:(北京地铁项目)