GitHub
https://github.com/silkworm4379/subway_line
项目简介
实现北京地铁线路乘坐的最少站点查询。
实现语言:Java
开发环境:win10 Intellij IDEA
项目内容
TXT文件格式
总共需要两个TXT文件,一个存储线路,一个存储换站信息
结构
结构是用邻接表和点集信息,点集信息中存储换站有关信息
1 public class AMGraph { 2 String[] vexs = null;//点集信息 3 public int[][] distance = null;//int[][] arr =new int[3][5] 4 public int [][] matrix_dist=null;//距离矩阵 5 public int [][] matrix_path=null;//路径矩阵 6 } 7 8 public class line { 9 public ArrayListl=null; 10 } 11 12 public class Vexs { 13 public static int vnumber=0; 14 public static String line_result=null; 15 16 public line [] x=null; 17 public ArrayList stationmap=null; 18 public Map mapline =null; 19 20 public ArrayList station=null; 21 public Map map =null; //数据采用的哈希表结构 22 23 public Vexs(){ 24 25 } 26 27 public Vexs(String [] station){ 28 int num=0; 29 num=station.length; 30 this.station=new ArrayList (num); 31 for(int i=0;i ){ 32 this.station.set(i,station[i]); 33 } 34 35 } 36 37 }
读取程序完成main函数功能
1 public static void Read(String fileName,String fileName2) { 2 Scanner input=new Scanner(System.in); 3 File file = new File(fileName); 4 Vexs v=new Vexs(); 5 AMGraph g=new AMGraph(); 6 try { 7 System.out.println("以字符为单位读取文件内容,一次读多个字节:"); 8 9 BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8")); 10 String s=null; 11 ArrayListarraylist=new ArrayList (); 12 v.map = new HashMap (); 13 while ((s = br.readLine()) != null&&!s.equals("")) {//使用readLine方法,一次读一行 14 String[] splitted = s.split(" "); 15 arraylist.add(splitted[0]); 16 arraylist.add(splitted[1]); 17 } 18 v.station = new ArrayList<>(new LinkedHashSet<>(arraylist)); 19 for(int i=0;i ){ 20 v.map.put(v.station.get(i),i); 21 } 22 br.close(); 23 //读入转站信息 24 File file1=new File(fileName2); 25 v.mapline=new HashMap (); 26 StringBuilder result2 = new StringBuilder(); 27 BufferedReader br2 = new BufferedReader(new InputStreamReader(new FileInputStream(file1), "UTF-8")); 28 v.x=new line[500]; 29 ArrayList arraylist2=new ArrayList (); 30 while ((s = br2.readLine()) != null&&!s.equals("")) {//使用readLine方法,一次读一行 31 String[] splitted = s.split(" "); 32 v.x[Vexs.vnumber]=new line(); 33 v.x[Vexs.vnumber].l=new ArrayList (); 34 for(int j=0;j ){ 35 if(j==0){ 36 arraylist2.add(splitted[j]); 37 } 38 else{ 39 v.x[Vexs.vnumber].l.add(splitted[j]); 40 } 41 42 43 } 44 Vexs.vnumber++; 45 } 46 v.stationmap = new ArrayList<>(new LinkedHashSet<>(arraylist2)); 47 for(int i=0;i ){ 48 v.mapline.put(v.stationmap.get(i),i); 49 } 50 br2.close(); 51 52 53 g.distance=new int[v.station.size()][v.station.size()]; 54 g.matrix_dist=new int[v.station.size()][v.station.size()]; 55 g.matrix_path=new int[v.station.size()][v.station.size()]; 56 for(int i=0;i ){ 57 int a=v.map.get(arraylist.get(i)); 58 int b=v.map.get(arraylist.get(i+1)); 59 g.distance[a][b]=1; 60 g.distance[b][a]=1; 61 } 62 } catch (Exception e1) { 63 e1.printStackTrace(); 64 } 65 66 System.out.println("请输入两个站点的名称(站点之间加空格):"); 67 String a=input.next(); 68 String b=input.next(); 69 70 floyd(g,v,a,b); 71 ArrayList result=getPath(g,v,a,b); 72 String before=new String(v.station.get(result.get(result.size()-1))); 73 String after=new String(v.station.get(result.get(result.size()-1))); 74 String now=new String(v.station.get(result.get(result.size()-1))); 75 int needchange=0; 76 for(int i=result.size()-1;i>=0;i--){ 77 if(i>1&&i )); 78 now=v.station.get(result.get(i)); 79 if(isChange(g, v, before,after)&&i>1&&i ){ 80 needchange=1; 81 } 82 83 if(needchange==1&&i ){ 84 if(has(g, v, v.station.get(result.get(i-1)), v.station.get(result.get(i-2)))){ 85 System.out.println("转站"+Vexs.line_result); 86 } 87 } 88 89 before=v.station.get(result.get(i)); 90 System.out.print(v.station.get(result.get(i))+" "); 91 needchange=0; 92 93 94 } 95 }
用Floyd算法实现功能
public static void floyd(AMGraph g,Vexs v,String a,String b){ for (int i=0;i< v.station.size();i++) for (int j = 0; j < v.station.size(); j++) { g.matrix_dist[i][j] = g.distance[i][j];//初始化距离矩阵 g.matrix_path[i][j] = i;//初始化路径矩阵 } int temp=0; //三重循环 for (int k = 0; k < v.station.size(); k++) { for (int i = 0; i < v.station.size(); i++) { for (int j = 0; j < v.station.size(); j++) { if (g.matrix_dist[i][k] != 0 && g.matrix_dist[k][j] != 0) if ((temp = g.matrix_dist[i][k] + g.matrix_dist[k][j]) < g.matrix_dist[i][j] || g.matrix_dist[i][j] == 0) { //更新距离和路径 g.matrix_dist[i][j] = temp; g.matrix_path[i][j] = g.matrix_path[k][j]; } } } } }
读取路径方法
1 public static ArrayListgetPath(AMGraph g,Vexs v,String a,String b){ 2 int k; 3 k = v.map.get(b); 4 ArrayList res=null; 5 if (g.matrix_dist[v.map.get(a)][v.map.get(b)] == 0){ 6 return res; 7 } 8 res=new ArrayList (); 9 while (k != v.map.get(a)){ 10 res.add(k); 11 k = g.matrix_path[v.map.get(a)][k]; 12 } 13 res.add(k); 14 15 return res; 16 }
换站有关方法
1 public static boolean isChange(AMGraph g,Vexs v,String a,String b){ 2 if(has(g, v, a, b)){ 3 return false; 4 } 5 6 return true; 7 } 8 9 public static boolean has(AMGraph g,Vexs v,String a,String b){ 10 for(int i=0;i){ 11 for(int j=0;j ){ 12 if(v.x[v.mapline.get(a)].l.get(i).equals(v.x[v.mapline.get(b)].l.get(j))){ 13 Vexs.line_result=v.x[v.mapline.get(a)].l.get(i); 14 return true; 15 } 16 } 17 18 } 19 20 return false; 21 }
个人总结
这个项目处理起来还算简单,在最后打印换站信息的时候被小坑了一把,变量名设置得太相似导致用错变量。其次存储格式有些冗余,完全可以去掉一部分信息,手动输入十分麻烦。