java实现北京地铁换乘
文章目錄
- 項目GitHub地址
- 文件存放 station.txt
- 設(shè)計思路與模塊分析
- Station.java
- DataBuilder.java
- StationIncludeLineName.java
- Subway.java
- 計算從s1站到s2站的最短經(jīng)過路徑, 并輸出文件
- 獲得station到各個站的最短距離
- 得到所求的Station所在路線的所有站點
- 文件寫入
- 主函數(shù). 使用參數(shù)化運行的方法
- 測試
- 需求1
- 需求2
- 需求3
- 輸入?yún)?shù)有誤
- 路線不存在的情況
項目GitHub地址
https://github.com/yonginggg/BeijingSubwayTransfer
文件存放 station.txt
1號線 蘋果園 古城 八角游樂園 八寶山 玉泉路 五棵松 萬壽路 公主墳 軍事博物館 木樨地 南禮士路 復(fù)興門 西單 天安門西 天安門東 王府井 東單 建國門 永安里 國貿(mào) 大望路 四惠 四惠東 2號線 西直門 車公莊 阜成門 復(fù)興門 長椿街 宣武門 和平門 前門 崇文門 北京站 建國門 朝陽門 東四十條 東直門 雍和宮 安定門 鼓樓大街 積水潭 西直門 3號線 天宮院 生物醫(yī)藥基地 義和莊 黃村火車站 黃村西大街 清源路 棗園 高米店南 高米店北 西紅門 新宮 公益西橋 角門西 馬家堡 北京南站 陶然亭 菜市口 宣武門 西單 靈境胡同 西四 平安里 新街口 西直門 動物園 國家圖書館 魏公村 人民大學(xué) 海淀黃莊 中關(guān)村 北京大學(xué)東門 圓明園 西苑 北宮門 安河橋北 5號線 宋家莊 劉家窯 蒲黃榆 天壇東門 磁器口 崇文門 東單 燈市口 東四 張自忠路 北新橋 雍和宮 和平里北街 和平西橋 惠新西街南口 惠新西街北口 大屯橋東 北苑路北 立水橋南 立水橋 天通苑南 天通苑 天通苑 6號線 金安橋 楊莊 西黃村 廖公莊 田村 海淀五路居 慈壽寺 花園橋 白石橋南 車公莊西 車公莊 平安里 北海北 南鑼鼓巷 東四 朝陽門 東大橋 呼家樓 金臺路 十里堡 青年路 褡褳坡 黃渠 常營 草房 物資學(xué)院路 通州北關(guān) 通運門 北運河西 北運河?xùn)| 郝家府 東夏園 潞城 7號線 北京西站 灣子 達(dá)官營 廣安門內(nèi) 菜市口 虎坊橋 珠市口 橋灣 磁器口 廣渠門內(nèi) 廣渠門外 九龍山 大郊亭 百子灣 化工 南樓梓莊 歡樂谷景區(qū) 垡頭 雙合 焦化廠 8號線 朱辛莊 育知路 平西府 回龍觀東大街 霍營 育新 西小口 永泰莊 林萃橋 森林公園南門 奧林匹克公園 奧體中心 北土城 安華橋 安德里北街 鼓樓大街 什剎海 南鑼鼓巷 中國美術(shù)館 8號線南段 珠市口 天橋 永定門外 木樨園 海戶屯 大紅門南 和義 東高地 火箭萬源 五福堂 德茂 瀛海 9號線 國家圖書館 白石橋南 白堆子 軍事博物館 北京西站 六里橋東 六里橋 七里莊 豐臺東大街 豐臺南路 科怡路 豐臺科技園 郭公莊 10號線 勁松 雙井 國貿(mào) 金臺夕照 呼家樓 團(tuán)結(jié)湖 農(nóng)業(yè)展覽館 亮馬橋 三元橋 太陽宮 芍藥居 惠新西街南口 安貞門 北土城 健德門 牡丹園 西土城 知春路 知春里 海淀黃莊 蘇州街 巴溝 火器營 長春橋 車道溝 慈壽寺 西釣魚臺 公主墳 蓮花橋 六里橋 西局 泥洼 豐臺站 首經(jīng)貿(mào) 紀(jì)家廟 草橋 角門西 角門東 大紅門 石榴莊 宋家莊 成壽寺 分鐘寺 十里河 潘家園 勁松 新機(jī)場線 草橋 大興新城 大興機(jī)場 13號線 西直門 大鐘寺 知春路 五道口 上地 西二旗 龍澤 回龍觀 霍營 立水橋 北苑 望京西 芍藥居 光熙門 柳芳 東直門 14號線西端 張郭莊 園博園 大瓦窯 郭莊子 打井 七里莊 西局 14號線東端 北京南站 永定門外 景泰 蒲黃榆 方莊 十里河 北工大西門 平樂園 九龍山 大望路 金臺路 朝陽公園 棗營 東風(fēng)北橋 將臺 望京南 阜通 望京 東湖渠 來廣營 善各莊 15號線 俸伯 順義 石門 南法信 后沙峪 花梨坎 國展 孫河 馬泉營 崔各莊 望京東 望京 望京西 關(guān)莊 大屯路東 安立路 奧林匹克公園 北沙灘 六道口 清華東路西口 16號線 北安河 溫陽路 稻香湖路 屯佃 永豐 永豐南 西北旺 馬連洼 農(nóng)大南路 西苑 八通線 四惠 四惠東 高碑店 傳媒大學(xué) 雙橋 管莊 八里橋 通州北苑 果園 九棵樹 梨園 臨河里 土橋 昌平線 昌平西山口 十三陵景區(qū) 昌平 昌平關(guān)東 北邵洼 南邵 沙河高教園 沙河 鞏華城 朱辛莊 生命科學(xué)園 西二旗 亦莊線 宋家莊 肖村 小紅門 舊宮 亦莊橋 亦莊文化園 萬源街 榮京東街 榮昌東街 同濟(jì)南路 經(jīng)海路 次渠南 次渠 亦莊火車站 房山線 郭公莊 大葆臺 稻田 長陽 籬笆房 廣陽城 良鄉(xiāng)大學(xué)城北 良鄉(xiāng)大學(xué)城 良鄉(xiāng)大學(xué)城西 良鄉(xiāng)南關(guān) 蘇莊 閻村東 機(jī)場線 東直門 三元橋 T2航站樓 T3航站樓 s1號線 金安橋 四道橋 橋戶營 上岸 栗園莊 小園 石廠 燕房線 燕山 房山城關(guān) 饒樂府 馬各莊 大石河?xùn)| 星城 閻村 紫草塢 閻村東 西郊線 香山 植物園 萬安 茶棚 頤和園西門 巴溝設(shè)計思路與模塊分析
Station.java
定義了站點Station的類結(jié)構(gòu)和圖的結(jié)構(gòu)
import java.util.HashMap; import java.util.HashMap; import java.util.LinkedHashSet; import java.util.Map;public class Station {private String name; //地鐵站名稱public Station prev; //前一個站public Station next; //后一個站//本站到某一個目標(biāo)站(key)所經(jīng)過的所有站集合(value),保持前后順序private Map<Station, LinkedHashSet<Station>> orderSetMap = new HashMap<Station, LinkedHashSet<Station>>();public Station(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}public LinkedHashSet<Station> getAllPassedStations(Station station) {if (orderSetMap.get(station) == null) {LinkedHashSet<Station> set = new LinkedHashSet<Station>();set.add(this);orderSetMap.put(station, set);}return orderSetMap.get(station);}public Map<Station, LinkedHashSet<Station>> getOrderSetMap() {return orderSetMap;}@Overridepublic 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;}}@Overridepublic int hashCode() {return this.getName().hashCode();} }DataBuilder.java
讀取文件,創(chuàng)建地鐵路線(得到的是去除了第一列后的站點的集合以及總的站點的數(shù)量
得到的站點信息以HashSet<List< Station>> lineSet的形式保存, 每一個list保存的是其中一條線路的信息
StationIncludeLineName.java
讀取文件,創(chuàng)建地鐵路線(得到的是沒有去除了第一列后的set
import java.util.*; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader;public class StationIncludeLineName {public static HashSet<List<Station>> lineSet = new HashSet<List<Station>>();//所有線集合public static int totalStaion = 0;//總的站點數(shù)量//讀取文件public static void readFile(String fileName) throws IOException{FileInputStream inputStream = new FileInputStream(fileName); // FileInputStream inputStream = new FileInputStream("station.txt");BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));String str = null;while((str = bufferedReader.readLine()) != null){List<Station> line = new ArrayList<Station>();String[] lineInformations = str.split(" ");for(String s : lineInformations){line.add(new Station(s));}for(int i =0;i<line.size();i++){if(i<line.size()-1){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
先創(chuàng)建一個outLIst存放讀取過的站點的信息; 一個allStation用來保存得到的最短路徑經(jīng)過的站點名字,用來進(jìn)行文件的生成操作
private List<Station> outList = new ArrayList<Station>(); String allStations = "";計算從s1站到s2站的最短經(jīng)過路徑, 并輸出文件
遍歷所有的線路信息,并將遍歷過的station添加到List< Station> outList中, 當(dāng)outList.size() == DataBuilder.totalStaion即全部遍歷后, 使用Station station : s1.getAllPassedStations(s2)得到s1到s2的路線并將名字保存到allStations
public String calculate(Station s1, Station s2) {//長度相等級找完了全部的路徑,輸出文件if (outList.size() == DataBuilder.totalStaion) { // System.out.println("找到目標(biāo)站點:" + s2.getName() + ",共經(jīng)過" + (s1.getAllPassedStations(s2).size() - 1) + "站");allStations+="找到目標(biāo)站點:" + s2.getName() + ",共經(jīng)過" + (s1.getAllPassedStations(s2).size() - 1) + "站"+"\n";for (Station station : s1.getAllPassedStations(s2)) { // System.out.print(station.getName() + "->");allStations+=station.getName() + "->";}return allStations;}if (!outList.contains(s1)) {outList.add(s1);}//如果起點站的OrderSetMap為空,則第一次用起點站的前后站點初始化之if (s1.getOrderSetMap().isEmpty()) {List<Station> Linkedstations = getAllLinkedStations(s1);for (Station s : Linkedstations) {s1.getAllPassedStations(s).add(s);}}Station parent = getShortestPath(s1);//獲取距離起點站s1最近的一個站if (parent == s2) { // System.out.println("找到目標(biāo)站點:" + s2 + ",共經(jīng)過" + (s1.getAllPassedStations(s2).size() - 1) + "站");allStations+="找到目標(biāo)站點:" + s2 + ",共經(jīng)過" + (s1.getAllPassedStations(s2).size() - 1) + "站"+"\n";for (Station station : s1.getAllPassedStations(s2)) { // System.out.print(station.getName() + "->");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已經(jīng)計算過到此child的經(jīng)過距離,那么比較出最小的距離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的經(jīng)過距離s1.getAllPassedStations(child).addAll(s1.getAllPassedStations(parent));s1.getAllPassedStations(child).add(child);}}outList.add(parent);calculate(s1, s2);//重復(fù)計算,往外面站點擴(kuò)展return allStations;}獲得station到各個站的最短距離
定義一個MAX_VALUE, 然后使用getAllPassedStations的方法來得到station到s所經(jīng)過的所有站點的集合,返回它的size即距離
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<Station> set = station.getAllPassedStations(s);//參數(shù)station到s所經(jīng)過的所有站點的集合if (set.size() < minPatn) {minPatn = set.size();rets = s;}}return rets;}得到所求的Station所在路線的所有站點
循環(huán)遍歷從文件中讀取到的所有線路信息, 如果所求的Station包含在該線路中, 將這一線路返回
private List<Station> getAllLinkedStations(Station station) {List<Station> linkedStaions = new ArrayList<Station>();for (List<Station> 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();}}主函數(shù). 使用參數(shù)化運行的方法
使用正則表達(dá)式去匹配
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<Station> 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<Station> 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)); // System.out.println(allStations);writeFileString(allStations, writeFile);}else{System.out.println("輸入?yún)?shù)有誤");}}測試
需求1
程序啟動時需要通過讀取 -map 參數(shù)來獲得對應(yīng)的自定義地鐵文件(命名為 subway.txt),從而得到地鐵線路圖的信息。
java subway -map subway.txt需求2
在給定地鐵線路時,你的程序就需要能夠從線路的起始站點開始,依次輸出該地鐵線經(jīng)過的所有站點,直到終點站
java subway -a 1號線 -map subway.txt -o station.txt需求3
給出起點和終點, 保存路徑信息到文件中
subway.exe -b 香山 焦化廠 -map subway.txt -o routine.txt
輸入?yún)?shù)有誤
路線不存在的情況
總結(jié)
以上是生活随笔為你收集整理的java实现北京地铁换乘的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: interlace和progressiv
- 下一篇: 网络安全篇 防火墙的静态路由-04