结对作业:地铁查询系统

1、数据库设计: 1.1存储:线路号,车站唯一标识ID,线路的各个站名,车站的换乘信息等信息。

1.2需要考虑:如何表示两个小白圆点中间有一条线表示这两个车站是相邻的;这个车站可以转 5 号线等信息。

2、功能设计:

线路查询:输入线路号,输出此地铁线路的所有站名(按某一方向顺序输出即可)。

站点查询:输入站点名称,输出途径该站点的线路名称。

起点-终点查询:输入起点、终点,找到两点之间的最有效线路 起点:知春路 终点:中关村 返回经历的站名的个数,和路径,如果有换乘,请列出换乘的线路, 例如: 4 知春路(地铁10号线) 知春里 海淀黄庄 换乘4号线(安定桥河北方向) 中关村

 

我的结对队友是郝家枫,第一阶段还算顺利

主模块

 

复制代码
package main;
import manager.*;


public class Main {
    //主函数
    public static void main(String[] args) throws Exception {
        //-map 地图读入
        if(args[0].equals("-map")){
            readMap(args[1]);
            System.out.println("地图读取成功!");
        }
        // -a 地铁线站点输出
        else if (args[0].equals("-a")){
            readMap(args[3]);
            manager.LineManager.check(args[1]);
            //读取
            FileWrite.outstation(args[1],args[5]);
            System.out.println("车站信息输出成功!");
        }
        // -b 最短路径查询
        else if(args[0].equals("-b")){
            readMap(args[4]);
            ShortestPath.makeTb();
            //读取输出文件,起点和终点
            FileWrite.outroutine(args[6],args[1],args[2]);
            System.out.println("路线信息输出成功!");
        }
        else{
            System.out.println("请输入指定命令进行相应操作!");
        }
    }
    //地图文件读取
    public static void readMap(String x) throws Exception {
        String readfile =x;
        manager.Map.in(readfile);
        manager.LineManager.statisticsStation();
        manager.Map.getHashMap();
        Map.setMap();
        manager.LineManager.readline(readfile);
    }

}
复制代码

 

 

 

  我先设计了station和line两个类,用于储存地铁站,地铁线路和其他相关信息

station

 

复制代码
package model;

import java.util.*;
public class Station {
    private String stationName;     //站点名称
    private Set<Line>lineName;      //所属地铁线
    private Set<Station>linkStations; //相连的地铁站

    //获得站点名称
    public String getStationName() {

        return stationName;
    }

    //获得站点相连的站点
    public Set<Station> getlinkStations() {

        return linkStations;
    }

    //为站点添加所在地铁线
    public void addLineName(Line lineName) {

        this.lineName.add(lineName);
    }

    //为当前站点添加相邻站点
    public void addlinkStations(Station linkStations) {

        this.linkStations.add(linkStations);
    }

    //添加一个站点包括它的名称,附近相连站点,所在线路站点
    public Station(String stationName) {
        this.stationName=stationName;
        linkStations= new HashSet<>();
        lineName= new HashSet<>();
    }
}
复制代码

 

 

 

 

line

复制代码
package model;
import java.util.*;
public class Line {
    private List<Station>stations;   //所经过站点
    //返回地铁站当前的站点
    public List<Station> getStations() {
        return stations;
    }

    //为地铁线路添加站点
    public void addStation(Station station) {
        this.stations.add(station);
    }

    //添加地铁线和其经过的站点
    public Line() {
        stations= new ArrayList<>();
    }
}
复制代码

再将subway.txt的格式设计为

s1号线 金安桥 四道桥 桥户营 上岸 栗园庄 小园 石厂
1号线 苹果园 古城 八角游乐园 八宝山 玉泉路 五棵松 万寿路 公主坟 军事博物馆 木樨地 南礼士路 复兴门 西单 天安门西 天安门东 王府井 东单 建国门 永安里 国贸 大望路 四惠 四惠东
2号线 西直门 车公庄 阜成门 复兴门 长椿街 宣武门 和平门 前门 崇文门 北京站 建国门 朝阳门 东四十条 东直门 雍和宫 安定门 鼓楼大街 积水潭 西直门

方便程序读入。

在这之后便是要将储存的数据转化为HashMap并制作矩阵(为后面使用弗洛伊德算法做准备),这里我设计了manager.Map类。

接下来就是算法模块的,本次需求要求实现的功能主要有3点,一是实现地图的读取(已在IO模块实现),二是输出指定路线所经过的站点,三是根据输入的2个不同站点,输出最短线路(经过站最少)。

输出指点站点线路的工作比较简单,我设计了line模块解决

复制代码
package manager;

import model.Station;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class LineManager {
    public static java.util.Map<String, model.Line> lines;

    public static List<String> check(String linename){
        model.Line line=lines.get(linename);
        List<Station>stations=line.getStations();
        List<String>strings=new ArrayList<String>();
        for(Station station:stations){
            strings.add(station.getStationName());
        }
        return strings;
    }

    public static Set<List<String>> readline(String filename) throws Exception {
        FileInputStream inputStream = new FileInputStream(filename);
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        Set<List<String>>set=new HashSet<List<String>>();
        String str = null;
        while ((str = bufferedReader.readLine()) != null) {

            String[] lineInformations = str.split(" ");
            List<String>stations=new ArrayList<String>();
            for (String s : lineInformations) {
                stations.add(s);

            }
            set.add(stations);
        }
        //close
        inputStream.close();
        bufferedReader.close();
        return set;
    }
    public static void statisticsStation() {
        for (List<String> lineList : manager.Map.listSet)
            for (int i = 1; i < lineList.size(); i++)
                manager.Map.set.add(lineList.get(i));
    }
}
复制代码

接下来是比较难的寻找最短路径模块

复制代码
package manager;

import model.Station;
import java.util.ArrayList;
import java.util.List;

public class ShortestPath {
    public static int len;
    public static int[][] path;
    public static int[][] dist;
    public static int[][] table;
    public static int INF = Integer.MAX_VALUE;   //设置INF无限大
    public static List<Integer> result = new ArrayList<Integer>();
    public static void findFloydRoad(int[][] table) {
        int size = len;
        path = new int[size][size];
        dist = new int[size][size];
        //initialize dist and path
        System.out.println(size);
        for (int i = 0; i < size; i++) {
            for (int j = 0; j < size; j++) {
                path[i][j] = -1;
                dist[i][j] = table[i][j];
            }
        }
        for (int k = 0; k < size; k++) {
            for (int i = 0; i < size; i++) {
                for (int j = 0; j < size; j++) {
                    if (dist[i][k] != INF &&
                            dist[k][j] != INF &&
                            dist[i][k] + dist[k][j] < dist[i][j]) {
                        dist[i][j] = dist[i][k] + dist[k][j];
                        path[i][j] = k;
                    }
                }
            }
        }

    }
    public static void makeTb(){
        len = manager.Map.map.size();
        table =new int[len][len];
        for(int i=0;i<len;i++){
            for(int  j=0;j<len;j++){
                table[i][j]=INF;
            }
        }
        for(int i=0;i<len;i++){
            Station station=manager.Map.map.get(i);
            for(Station s:station.getlinkStations()){
                int j=manager.Map.numMap.get(s.getStationName());
                table[i][j]=1;
                table[j][i]=1;
            }
        }
    }
    public static void findCheapestPath(int begin, int end, int[][] table) {
        ShortestPath.findFloydRoad(table);
        result.add(begin);
        findPath(begin, end);
        result.add(end);
    }

    public  static void findPath(int i, int j) {
        int k = path[i][j];
        if (k == -1)        //当k=-1时,递归结束,否则一直递归
            return ;
        else {
            findPath(i, k);
            result.add(k);
            findPath(k, j);
        }
    }
}
复制代码

在完成这些工作后,便要设计输出模块,将相关结果输出到txt文件中 这里我设计了FileWrite类专门解决这个问题

复制代码
package manager;
import main.Main;
import model.Station;
import java.io.*;


public class FileWrite {
    public static void outstation(String linename,String fileName) throws Exception {
        if(fileName.equals("")||fileName.equals(" ")){
            System.out.println("输出文件名不能为空!");
        }
        else if(linename.equals("")||linename.equals(" ")){
            System.out.println("查询线路名不能为空");
        }
        else {
            BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName)));
            out.write(linename+"所经过的站点有");
            out.newLine(); //换行
            for (Station s : manager.LineManager.lines.get(linename).getStations()) {
                out.write(s.getStationName());
                out.newLine();
            }
            out.flush();
            out.close();
        }


    }

    public static void outroutine(String fileName,String a,String b) throws Exception {
        if(fileName.equals("")||fileName.equals(" ")){
            System.out.println("输出文件名不能为空!");
        }
        else {
            int x =manager.Map.numMap.get(a);
            int y =manager.Map.numMap.get(b);
            ShortestPath.findCheapestPath(x, y, ShortestPath.table);
            BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName)));
            out.write(" 从 " + manager.Map.map.get(x).getStationName() + " 到 " + manager.Map.map.get(y).getStationName() + " 一共历经" + ShortestPath.dist[x][y] + "站" + " 的最佳路径是 ");
            out.newLine();  //换行
            for (int r : ShortestPath.result) {
                if (!manager.Map.map.get(r).getStationName().equals(manager.Map.map.get(x).getStationName())) {
                    out.write("  |");
                    out.newLine();
                }
                out.write(manager.Map.map.get(r).getStationName());
                out.newLine();
            }
            out.flush();
            out.close();
        }
    }
}
复制代码

完成到这一步,基本完成了实验需求

 

二.程序测试

1  -map subway.txt

 

-a 1号线 -map subway.txt -o station.txt

 

 

 

 

 

 

-b 苹果园 北京站 -map subway.txt -o routine.txt

 

 

 

 

 

 

 4. -c

 然后完善了此地铁系统,做了完整的界面显示连接数据库

 

 

 

 

 

 

 

三.心得总结

  本次个人实验让我个人有许多收获,在本次实验前,我对Java的理解与掌握更多是在数据库方面,而这次实验让我对Java的IO ,交互和算法实现的方面有了更清晰的认识。更重要的是,我对软件工程和软件设计过程有了一个比较清晰的认识,并了解了软件工程的具体流程。虽然这次实验参考了大量的外部资料并仍存在许多不足,但是这次实验就行打开软件工程大门的敲门砖,让我收获匪浅,也对团队协作有了更深的认识

 

posted on 2022-04-07 21:55  GHOST-CR  阅读(201)  评论(0)    收藏  举报