地铁最短路径(代码部分)
Posted mmd123
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了地铁最短路径(代码部分)相关的知识,希望对你有一定的参考价值。
地铁线路的信息保存在一份文本文档中,格式为:
地铁线路总数
线路名1 站名1 站名2 站名3 ...
线路名2 站名1 站名2 站名3 ...
线路名3 站名1 站名2 站名3 ......
1.主要功能
1.实现一个支持显示地铁线路与计算换乘的程序
2.查询指定地铁线经过的站点
3.用户希望能获得以最少的站数从出发点到达目的地的路径
2.实现语言
java
3.实现算法
BFS(广度优先算法)
4.类职责划分
public static HashMap<String,station> Map = new HashMap<>();//查找站点信息
public static List
5.核心代码(主要部分)
public static void readSubway(String way) {//从TXT中读入线路数据
try {
InputStreamReader reader = new InputStreamReader(new FileInputStream(way));
BufferedReader read1 = new BufferedReader(reader);
String read = "";
read = read1.readLine();//线路数量
int num = 0;
num = Integer.parseInt(read);
for (int i = 0; i <= num; i++) {
line line = new line();//当前存的路线
read = read1.readLine();
if(read==null){
return;
}
String[] stations = read.split(" ");//读入的line对应的所有station
line.setLineName(stations[0]);//地铁线路名
for (int j = 1; j < stations.length - 1; j++) {
station station1 = new station();//当前line中的station
station station2 = new station();
if (Map.containsKey(stations[j])) {//如果map中已经有该站点则把这个站点拿出来处理
station1 = Map.get(stations[j]);
Map.remove(stations[j]);
} else {
station1.setStationName(stations[j]);
station1.setVisited(false);
}
if (Map.containsKey(stations[j + 1])) {//Map中已经有该站后面的站点拿出来处理
station2 = Map.get(stations[j + 1]);
Map.remove(stations[j + 1]);
} else {
station2.setStationName(stations[j + 1]);
station2.setVisited(false);
}
if (!station1.getLine().contains(line.getLineName()))//如果当前站未加入line中,则在line中当前站名
station1.AddStationLine(line.getLineName());
if (!station2.getLine().contains(line.getLineName()))
station2.AddStationLine(line.getLineName());
if (!station1.getLinkStations().contains(station2))
station1.AddLinkStation(station2);
if (!station2.getLinkStations().contains(station1))
station2.AddLinkStation(station1);
station1.setPreStation(station1.getStationName());
station2.setPreStation(station2.getStationName());
Map.put(stations[j], station1);//把station1放回Map
Map.put(stations[j + 1], station2);//把station2放回Map
if (!line.getStations().contains(station1.getStationName())) {
line.stationAdd(station1.getStationName());
}
if (!line.getStations().contains(station2.getStationName())) {
line.stationAdd(station2.getStationName());
}
}
LineSet.add(line);//把线路加入LineSet
}
read1.close();
}catch(Exception e){
e.printStackTrace();
}
}
public static void searchline(String line){ //根据线路名字查找该线路所有站点
int flag = 0;
int index = -1;
for (line line1 :LineSet){
index++;
if(line1.getLineName().equals(line)) {
flag = 1;
break;
}
}
if (flag==0)
System.out.println("该地铁线路不存在");
else {
System.out.print(line + ": ");
for (String str : LineSet.get(index).getStations()) {
System.out.print(str + " ");
}
}
}
public static void BFS(String start,String end){//使用BFS广度优先算法计算
int sign = 0;
if (!Map.containsKey(start)){//判断start是否存在
System.out.println("start不存在");
sign = 1;
}
if (!Map.containsKey(end)){
System.out.println("end不存在");//判断end是否存在
sign = 1;
}
for (String temp :Map.keySet()){
Map.get(temp).setVisited(false);//初始化都设为false
Map.get(temp).setDistance(0);//初始化距离为0
}
station nowStation = new station();
Queue<String> queue = new LinkedList<>();//存放遍历过的站点
nowStation = Map.get(start);
queue.add(start);
while(!queue.isEmpty()){
String nowStationName = queue.poll();
Map.get(nowStationName).setVisited(true);
if (nowStation.getStationName().equals(end)){
break;
}
for (station station1 :Map.get(nowStationName).getLinkStations()){
if(!Map.get(station1.getStationName()).isVisited()){//未访问过的临近站点
Map.get(station1.getStationName()).setPreStation(nowStationName);//为preStation赋值
Map.get(station1.getStationName()).setDistance(Map.get(nowStationName).getDistance()+1);//临近站的距离为本站距离加1
queue.offer(station1.getStationName());
}
}
}
}
public static void path(String start,String end){//输出路径
if (start.equals(end)){
System.out.print("起点站与终点站相同 本站为:"+start);
return;
}
List<String> path = new ArrayList<>();
Stack<String> printline = new Stack<>();
int numStation = 1;//存放站数
String str = end;
while(!str.equals(start)){
path.add(str);
printline.push(str);
str = Map.get(str).getPreStation();
}
path.add(str);//把start放入path
printline.push(str);
for (int i=1;i<path.size()-1;i++){
if (Map.get(path.get(i)).getLine().size()==1){
continue;
}
String temp1="";
String temp2="";
for (String str1 : Map.get(path.get(i)).getLine()){//本站与前一站的共同拥有的线路存在temp1中
int flag=0;
for (String str2 :Map.get(path.get(i-1)).getLine()){
if (str1.equals(str2)){
temp1 = temp1+str1;
flag=1;
break;
}
}
if (flag==1)
break;
}
for (String str1 : Map.get(path.get(i)).getLine()){//后一站与本站的共同拥有的线路存在temp2中
int flag=0;
for (String str2 :Map.get(path.get(i+1)).getLine()){
if (str1.equals(str2)){
temp2 = temp2+str1;
flag=1;
break;
}
}
if (flag==1)
break;
}
if (!temp1.equals(temp2))//若temp1和temp2两线路不同则本站为转乘站
Map.get(path.get(i)).setIfchange(true);
}
//判断path中的换乘站
while(!printline.empty()){
String printStation = printline.pop();
if(numStation==1){
for (String strnow : Map.get(printStation).getLine()){
for (String nextStation : Map.get(path.get(path.size()-numStation-1)).getLine()){
if (strnow.equals(nextStation)) {
System.out.println("从"+strnow+"出发");
}
}
}
}
if (Map.get(printStation).isIfchange()){
String nowline ="";
for (String strnow : Map.get(printStation).getLine()){
for (String nextStation : Map.get(path.get(path.size()-numStation-1)).getLine()){
if (strnow.equals(nextStation))
nowline= nowline + strnow;
}
}
System.out.println(printStation);
System.out.println("转 "+nowline);
}
System.out.print(printStation+" ");
numStation++;
}
numStation =numStation-1;
System.out.println();
System.out.println("一共"+numStation+"站");//输出最后一共乘坐的站数
}
public static void main(String[] ards){
readSubway("E:\\原桌面\\大三上\\软件工程\\地铁.txt");
System.out.println("1.查询某条线路的所有站点");
System.out.println("2.查询某站到某站的最短线路");
System.out.print("请输入序号(1或者2):");
Scanner Scanner = new Scanner(System.in);
int input = Scanner.nextInt();
if (input==1){
System.out.print("请输入地铁线路名称:");
Scanner Scanner1 = new Scanner(System.in);
String linename = Scanner1.nextLine();
searchline(linename);
}
else if (input==2){
System.out.print("start:");
Scanner Scanner2 = new Scanner(System.in);
String start =Scanner2.nextLine();
System.out.print("end:");
String end = Scanner2.nextLine();
BFS(start,end);
path(start,end);
}
}
package test;
import java.util.*;
public class line {
private String LineName; //线名
private List<String> stations= new ArrayList<String>(); //该线路中所有站
public List<String> getStations() {
return stations;
}
public void setStations(List<String> stations) {
this.stations = stations;
}
public String getLineName() {
return LineName;
}
public void setLineName(String lineName) {
LineName = lineName;
}
public void stationAdd(String name){
stations.add(name);
}
}
package test;
import java.util.*;
public class station {
private String Name; //站点名
private List<String> Line = new ArrayList<String>(); //所在线路(如果是换乘点的话可以有多个)
private List<station> LinkStations= new ArrayList<station>(); //与之相邻的站点
private boolean visited;//是否访问过该站点
private String beforeStation;//本站之前访问的站点
private int distance=0;//本站距离起点站的站数
private boolean ifchange;//是否换乘 默认为false 用于结果
public boolean isIfchange() {
return ifchange;
}
public void setIfchange(boolean ifchange) {
this.ifchange = ifchange;
}
public int getDistance() {
return distance;
}
public void setDistance(int distance) {
this.distance = distance;
}
public void AddStationLine(String name){
Line.add(name);
}
public void AddLinkStation(station sta){
LinkStations.add(sta);
}
public String getStationName() {
return Name;
}
public void setStationName(String stationName) {
Name = stationName;
}
public List<String> getLine() {
return Line;
}
public void setLine(List<String> line) {
Line = line;
}
public List<station> getLinkStations() {
return LinkStations;
}
public void setLinkStations(List<station> linkStations) {
LinkStations = linkStations;
}
public boolean isVisited() {
return visited;
}
public void setVisited(boolean visited) {
this.visited = visited;
}
public String getPreStation() {
return beforeStation;
}
public void setPreStation(String preStation) {
this.beforeStation = preStation;
}
}
6.测试用例
1查询某条路线的所有站点:
不存在时:
2查询某站到某站的最短线路
起点和终点在一条线上时:
起点和终点在不同线上时:
输入不存在的起点:
输入不存在的终点:
全部代码详情请移步github:https://github.com/YuKeeMM/subway.git
7.总结
这是第一次使用博客园的方式发表,使用起来很不错。本次的作业有所难度,算法等其他方面都还有待改进,自己的代码能力还是不足,需要不断地练习。
以上是关于地铁最短路径(代码部分)的主要内容,如果未能解决你的问题,请参考以下文章