项目地址
详见:
一、基本功能
- 获取地铁线路图。
以参数 -map 作为标志,来获得对应的自定义地铁线路图信息文件(命名为 Subway.txt)。输入格式如:
java Subway -map Subway.txt
- 获取指定地铁线路。
以参数 -a 作为标志,并输入指定地铁线路,输出的文件以参数 -o 来指定。从线路的起始站点开始,依次输出该地铁线经过的所有站点,直到终点站。输入格式如:
java Subway -a 1号线 -map Subway.txt -o Station.txt
- 输入起始站点与目的站点,输出相应最短路线。
以 -b 参数作为标志,并输入起始站点与目的站点,输出经过的站点的个数和路径(包括起始站点与目的站点),如果需要换乘,则在换乘站的下一行输出换乘的地铁线路。将结果写入 routine.txt 中。输入格式如:
java Subway -b 苹果园 雍和宫 -map Subway.txt -o Routine.txt
二、文件存储
地铁线路图信息等都以txt的文件格式存储,以方便程序读取,简洁易懂,并可以灵活拓展。
- 地铁线路图信息——Subway.txt
1号线 苹果园 古城 八角游乐园 八宝山 玉泉路 五棵松 万寿路 公主坟 军事博物馆 木樨路 南礼士路 复兴门 西单 天安门西 天安门东 王府井 东单 建国门 永安里 国贸 大望路 四惠 四惠东
2号线 西直门 积水潭 鼓楼大街 安定门 雍和宫 东直门 东四十条 朝阳门 建国门 北京站 崇文门 前门 和平门 宣武门 长椿街 复兴门 阜成门 车公庄
……
- 地铁线所经站点——Station.txt
1号线 苹果园 古城 八角游乐园 八宝山 玉泉路 五棵松 万寿路 公主坟 军事博物馆 木樨路 南礼士路 复兴门 西单 天安门西 天安门东 王府井 东单 建国门 永安里 国贸 大望路 四惠 四惠东
- 起始站点与目的地间的最短路线——Routine.txt
需乘坐17个站点。
1号线:
苹果园
古城
八角游乐园
八宝山
玉泉路
五棵松
万寿路
公主坟
军事博物馆
(同站换乘)9号线:
白堆子
白石桥南
国家图书馆
(同站换乘)4号线大兴线:
动物园
西直门
(同站换乘)2号线:
积水潭
鼓楼大街
安定门
雍和宫
三、代码分析
- Subway.java
main函数
public static void main(String [] args) throws IOException{
// D:\eclipse-workspace\Subway\src
// chcp 936
new Subway();
// java Subway -map Subway.txt
if(args.length==2) {
new FileOperate(args[0], args[1]);
}
// java Subway -a 1号线 -map Subway.txt -o Station.txt
else if(args.length==6){
new FileOperate(args[0],args[1],args[2],args[3],args[4],args[5]);
}
// java Subway -b 苹果园 雍和宫 -map Subway.txt -o Routine.txt
else if(args.length==7){
new FileOperate(args[0],args[1],args[2],args[3],args[4],args[5],args[6]);
}
else{
System.out.println("ERROR!");
}
}
- Station.java
站点的结构
private String stationName;
private String lineName;
private List<Station> allLinkStations=new ArrayList<>();//所有相邻站点
public static LinkedHashSet<List<Station>> allLines=new LinkedHashSet<>();//所有地铁线路
- Path.java
路径的结构
private Station startStation;
private Station endStation;
private List<Station> allPassStations=new ArrayList<>();//所有
private int distance=0;
- FileOperate.java
对文件做读写操作,并判断不同情况。
public FileOperate(String str1, String str2) {
if(str1.equals("-map")){
for(int i=0;i<getFile(str2).size();i++){
getFilePrint(str2,i);
System.out.println("");
}
}else{
System.out.println("查询地铁线路图,请按照格式输入如:java Subway -map Subway.txt");
}
}
public FileOperate(String str, String str1, String str2, String str3, String str4, String str5) {
if(str.equals("-a") && str2.equals("-map") && str4.equals("-o")){
List<String> lines = getFile(str3);
int flag = 0;
for(int i=0;i<lines.size();i++) {
String[] lineAndStations = lines.get(i).split(" ");
if(lineAndStations[0].equals(str1)){
getFilePrint(str3,i);
// System.out.println(line.get(i));
writeFile(lines.get(i),str5);
flag = 1;
}
}
if(flag==0)
System.out.println("不存在此线路!");
}
else{
System.out.println("查询地铁线路,请按照格式输入如:java Subway -a 1号线 -map Subway.txt -o Station.txt");
}
}
public FileOperate(String str, String str1, String str2, String str3, String str4, String str5, String str6) throws IOException {
if(str.equals("-b") && str3.equals("-map") && str5.equals("-o")) {
if(str1.equals(str2))
System.out.println("起始站点与目的站点相同,请重新输入!");
List<String> lines = getFile(str4);
int flag1 = 0;
int flag2 = 0;
for(int i=0;i<lines.size();i++) {
String[] lineAndStations = lines.get(i).split(" ");
for(int j=1;j<lineAndStations.length;j++) {
if(lineAndStations[j].equals(str1)){
flag1 = 1;
}
if(lineAndStations[j].equals(str2)){
flag2 = 1;
}
}
}
if(flag1==0)
System.out.println("起始站点不存在!");
if(flag2==0)
System.out.println("目的站点不存在!");
// 获取最短路径getPath(start,end)
setAllLines(str4);
getRoutine(str6,str1,str2);
for(int i=0;i<getFile(str6).size();i++){
getFilePrint(str6,i);
}
}
else {
System.out.println("查询地铁线路,请按照格式输入如:java Subway -b 苹果园 雍和宫 -map Subway.txt -o Routine.txt");
}
}
- Dijkstra.java
Dijkstra算法,参考链接:https://juejin.im/entry/589049ea0ce4630056dc74d6
// 计算最短路径(相邻站点距离默认都为1)
public static Path getShortestPath(Station start, Station end) {
//添加起始站点
if (!outList.contains(start)) {
outList.add(start);
}
//第一次用起始站点的相邻站点初始化
if (path.isEmpty()) {
List<Station> allLinkStations = Station.getAllLinkStations(start);
for (Station station : allLinkStations) {
Path p = new Path();
p.setStartStation(start);
p.setEndStation(station);
int distance = 1;//起始站点距离初始为1
p.setDistance(distance);
p.getAllPassStations().add(station);//起始站点已经分析过
path.put(station, p);
}
}
// 获取下一站点
Station nextStation = getNextStation();
if (nextStation.equals(end)) {
return path.get(nextStation);
}
List<Station> nextLinkStations = Station.getAllLinkStations(nextStation);
for (Station station : nextLinkStations) {
// 已经分析过的station,不再做任何经分析
if (outList.contains(station)) {
continue;
}
//每增加一个站点,距离+1
int distance = path.get(nextStation).getDistance()+1;
List<Station> allPassStations = path.get(nextStation).getAllPassStations();
Path p = path.get(station);
if (p != null) {
//已经计算过到此station的距离比较出最小的距离
if (p.getDistance() > distance) {
p.setDistance(distance);
//重置start到各站的最小路径
p.getAllPassStations().clear();
p.getAllPassStations().addAll(allPassStations);
p.getAllPassStations().add(station);
}
}
else {//还没有计算过到此station的距离
p = new Path();
p.setDistance(distance);
p.setStartStation(start);
p.setEndStation(station);
p.getAllPassStations().addAll(allPassStations);
p.getAllPassStations().add(station);
}
path.put(station, p);
}
outList.add(nextStation);
getShortestPath(start, end);//重复计算,往外面站点扩展
return path.get(end);
}
四、测试分析
- 1、获取地铁线路图。
java Subway -map Subway.txt
1号线 苹果园 古城 八角游乐园 八宝山 玉泉路 五棵松 万寿路 公主坟 军事博物馆 木樨路 南礼士路 复兴门 西单 天安门西 天安门东 王府井 东单 建国门 永安里 国贸 大望路 四惠 四惠东
2号线 西直门 积水潭 鼓楼大街 安定门 雍和宫 东直门 东四十条 朝阳门 建国门 北京站 崇文门 前门 和平门 宣武门 长椿街 复兴门 阜成门 车公庄
……
当格式错误:
java Subway -ma Subwa.txt
查询地铁线路图,请按照格式输入如:java Subway -map Subway.txt
在以下两种输入中,都做了对此情况的相应的输出。
当文件不存在时:
java Subway -map Subwa.txt
Subwa.txt文件不存在!
在以下两种输入中,都做了对此情况的相应的输出。
- 2、获取指定地铁线路。
java Subway -a 1号线 -map Subway.txt -o Station.txt
1号线 苹果园 古城 八角游乐园 八宝山 玉泉路 五棵松 万寿路 公主坟 军事博物馆 木樨路 南礼士路 复兴门 西单 天安门西 天安门东 王府井 东单 建国门 永安里 国贸 大望路 四惠 四惠东
当指定线路不存在时:
java Subway -a 20号线 -map Subway.txt -o Station.txt
不存在此线路!
- 3、获取起始站点到目的站点最短线路。
无需换乘:
java Subway -b 苹果园 五棵松 -map Subway.txt -o Routine.txt
需乘坐5个站点。
1号线:
苹果园
古城
八角游乐园
八宝山
玉泉路
五棵松
需换乘:
java Subway -b 苹果园 雍和宫 -map Subway.txt -o Routine.txt
需乘坐17个站点。
1号线:
苹果园
古城
八角游乐园
八宝山
玉泉路
五棵松
万寿路
公主坟
军事博物馆
(同站换乘)9号线:
白堆子
白石桥南
国家图书馆
(同站换乘)4号线大兴线:
动物园
西直门
(同站换乘)2号线:
积水潭
鼓楼大街
安定门
雍和宫
当起始站点与目的站点一样时:
java Subway -b 苹果园 苹果园 -map Subway.txt -o Routine.txt
起始站点与目的站点相同,请重新输入!
当起始站点不存在:
java Subway -b 西湖 苹果园 -map Subway.txt -o Routine.txt
起始站点不存在!
当目的站点不存在:
java Subway -b 苹果园 西湖 -map Subway.txt -o Routine.txt
目的站点不存在!
五、个人小结
在完成个人项目的过程中,尽管与计划有所偏差,但还是很有收获的。从本次实验中,我觉得理清思路很重要,整个工程需要一个清晰的结构。不论是每一个java文件之间的结构,还是每一个函数之间的结构,还是数据存储的结构都十分重要,方便调用,也方便测试和修改。
另外,在命令行中出现过显示乱码的问题,可以用这一句解决:chcp 936。
地铁出行线路规划还是很贴近我们的生活的,我们只是用一个较为简单的方式,将线路查询功能模拟了出来。但我所做的这个项目还有不够完善的地方,主要是因为我没有合理分配好时间,只完成了基本功能,之后希望能做好结构和功能界面等方面的完善。
原文地址:https://www.cnblogs.com/qiyuexia3277/p/11675191.html