Github:https://github.com/Daisy-Yu/Subway-Beijing
语言:Java
所做工作:
1.文件的读取以及数据存储
2.输出指定地铁线路的所有站点
3.独立设计了UI
4.考虑了异常情况的控制
5.修改了算法
遇到的问题:
1.个人编程基础薄弱,能力不足,对于Dijkstra算法的掌握不熟练。
2.参考了网上的代码后,形成了思维定式,担心自己写的算法出现各种各样的差错,导致基本功能无法实现。
项目功能点:
- 输出指定地铁线路的所有站点
- 输出两地铁站点间的最短路径
项目设计:
1.地铁线路信息输入:subway.txt
1号线 站点1 站点2 站点3 ......
2号线 站点1 站点2 站点3 ......
3号线 站点1 站点2 站点3 ......
......
2.地铁线路以及各线路上站点的存放:
public static void readData(String filePath)——读取subway.txt
public static LinkedHashSet> lineSet = new LinkedHashSet<>();——所有线路的集合
Listline = new ArrayList ();——各线路上所有站点的集合
while((lineTxt = bufferedReader.readLine()) != null){ Listline = new ArrayList (); String[] lineArr = lineTxt.split(" "); String lineName=lineArr[0]; for(int j=1;j ) { line.add(new Station(lineArr[j],lineName)); } lineSet.add(line); }
按行读取,存入lineArr数组中,其中lineArr[0]为线路名称,往后是各个站点。
将站点信息放入对应线路中,再将线路信息放入线路集合中。
2.站点类Station:
private String sname;//站名 private String line;//所属线路 private Listlinks = new ArrayList<>();//相邻站点的集合
3.结果类Result:
private Station start;//起始站点 private Station over;//结束站点 private int distance = 0;//距离 private Listpass = new ArrayList<>();//经过站点的集合
功能实现:
1.输出指定地铁线路的所有站点:
public static void SearchLine(String filePath, String key) while((lineTxt = bufferedReader.readLine()) != null){ if(lineTxt.indexOf(key)==0) { System.out.println(lineTxt); } }
按行遍历文件,当某一行存在与输入的线路名称匹配的字符串时,indexOf()返回0,否则返回-1。输出indexOf()返回值为0的那一行的内容。
Console运行结果:
2.输出两地铁站点间的最短路径(Dijkstra算法)
private static HashMapresultMap = new HashMap<>();//结果集 private static List anaList = new ArrayList<>();//已经分析过的站点集
(1)找出相邻站点
private static ListgetLinkStation(Station station) { List linkedStaions = new ArrayList (); for (List line : Data.lineSet) {//遍历线的集合 for (int i = 0; i < line.size(); i++) { if (station.equals(line.get(i))) {//找到站所在的线 if (i == 0) {//如果是起始站 linkedStaions.add(line.get(i + 1));//将下一站加入该站的相邻站集合 } else if (i == (line.size() - 1)) {//如果是起始站 linkedStaions.add(line.get(i - 1));//将上一站加入该站的相邻站集合 } else {//如果是中间站,将上下两站加入该站的相邻站集合 linkedStaions.add(line.get(i + 1)); linkedStaions.add(line.get(i - 1)); } } } } return linkedStaions; }
(2)找出下一个分析点
private static Station getNextStation() { int min = 100;//权值初始化为100 Station dots = null; Setstations = resultMap.keySet(); for (Station station : stations) { if (anaList.contains(station)) {//如果站点已经分析过,继续 continue; } Result result = resultMap.get(station);//将站点放入结果集 if (result.getDistance() < min) { min = result.getDistance();//更新最小权值 dots = result.getOver();//根据最小权值找出下一个分析站点 } } return dots; }
(3)循环遍历更新result
public static Result value(Station start,Station over) { if (!anaList.contains(start)) {//将起始站放入已分析的站点集合 anaList.add(start); } if (start.equals(over)){//起始站点和结束站点相同,直接返回结果 Result result = new Result(); result.setDistance(0); result.setOver(start); result.setStart(start); resultMap.put(start, result); return resultMap.get(start); } if (resultMap.isEmpty()) {//结果集为空 ListlinkStations = getLinkStation(start); for (Station station : linkStations) { Result result = new Result(); result.setStart(start); result.setOver(station);//相邻站点放入result int distance = 1;//相邻站点间距离均为1 result.setDistance(distance); result.getPass().add(station);//该站加入经过站点集 resultMap.put(station, result);//放入结果集 } } Station before = getNextStation();//下一个分析站点 if (before==null){//不存在,即全部分析完 Result result = new Result(); result.setDistance(0); result.setStart(start); result.setOver(over); return resultMap.put(over, result); } if (before.equals(over)) {//下一个分析的站点是结束站点,即分析完 return resultMap.get(before); } List afterLinks = getLinkStation(before); for (Station after : afterLinks) {//分析before与相邻站点间的距离 if (anaList.contains(after)) { continue; } int distance = resultMap.get(before).getDistance()+1; if( before.getSname().equals(after.getSname())){ distance = 0; } List beforePass = resultMap.get(before).getPass(); Result afterResult = resultMap.get(after); if (afterResult!=null){//结果集中有内容 if (afterResult.getDistance() > distance) { afterResult.setDistance(distance); afterResult.getPass().clear();//清空 afterResult.getPass().addAll(beforePass);//更新 afterResult.getPass().add(after); } } else {//结果集中没有内容 afterResult = new Result();//新建 afterResult.setDistance(distance); afterResult.setStart(start); afterResult.setOver(after); afterResult.getPass().addAll(beforePass); afterResult.getPass().add(after); } resultMap.put(after, afterResult);//放入结果集 } anaList.add(before);//将下一个分析的站点加入已分析站点集 value(start, over);//递归调用 return resultMap.get(over);//全部分析完 }
Console运行结果:
界面设计:
采用GUI设计
异常控制:
1.站点不存在
2.起始站与终点站相同
3.线路不存在