项目要求与实现
1、读出.txt文件上的路线数据
2、实现北京地铁的线路查询和两站点最短路径查询
PSP表
PSP 2.1 | Personal Software Process Stages | Time |
---|---|---|
Planning | 计划 | |
· Estimate | · 估计这个任务需要多少时间 | 4h |
Development | 开发 | |
· Analysis | · 需求分析 (包括学习新技术) | 3h |
· Design Spec | · 生成设计文档 | 1h |
· Design Review | · 设计复审 (和同事审核设计文档) | 2h |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 2h |
· Design | · 具体设计 | 2h |
· Coding | · 具体编码 | 2h |
· Code Review | · 代码复审 | 3h |
· Test | · 测试(自我测试,修改代码,提交修改) | 3h |
Reporting | 报告 | |
· Test Report | · 测试报告 | 2h |
· Size Measurement | · 计算工作量 | 2h |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 2h |
--- | 合计 | 3d |
设计思路
数据存储
站点信息的数据存储在txt文件:
测试
1、需求1: -map subway.txt 获得对应的自定义地铁文件
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();
}
}
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
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
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));
writeFileString(allStations, writeFile);
}else{
System.out.println("输入参数有误");
}
}
}
2、需求2:-a 3号线 -map subway.txt -o station2.txt
假如输入 -a 100号线 -map subway.txt -o station2.txt的命令,
系统会提示该路线不存在
假如输入错误的命令,例如-c 100号线 -map subway.txt -o station2.txt的命令,
3、需求3:-b 苹果园 北京西站 -map subway.txt -o routine.txt
寻找两站之间的最短路径:
public class Subway {
private List
String allStations = "";
//计算从s1站到s2站的最短经过路径, 并输出文件
public String calculate(Station s1, Station s2) {
//长度相等级找完了全部的路径,输出文件
if (outList.size() == DataBuilder.totalStaion) {
// System.out.println("找到目标站点:" + s2.getName() + ",共经过" + (s1.getAllPassedStations(s2).size() - 1) + "站");
allStations+="找到目标站点:" + s2.getName() + ",共经过" + (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
for (Station s : Linkedstations) {
s1.getAllPassedStations(s).add(s);
}
}
Station parent = getShortestPath(s1);//获取距离起点站s1最近的一个站(有多个的话,随意取一个)
if (parent == s2) {
// System.out.println("找到目标站点:" + s2 + ",共经过" + (s1.getAllPassedStations(s2).size() - 1) + "站");
allStations+="找到目标站点:" + s2 + ",共经过" + (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已经计算过到此child的经过距离,那么比较出最小的距离
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的经过距离
s1.getAllPassedStations(child).addAll(s1.getAllPassedStations(parent));
s1.getAllPassedStations(child).add(child);
}
}
outList.add(parent);
calculate(s1, s2);//重复计算,往外面站点扩展
return allStations;
}
//取参数station到各个站的最短距离,相隔1站,距离为1,依次类推
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
if (set.size() < minPatn) {
minPatn = set.size();
rets = s;
}
}
return rets;
}
//获取参数station直接相连的所有站,包括交叉线上面的站
private List
List
for (List
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();
}
}
总结
通过地铁项目的构建初步掌握了markdown及github工具的运用,但需要后续的操作练习。此外,该项目已被很多程序员们编写过,可以通过读他们已有代码来学习这个最短路径算法。
通过这次实验更加加深了最短路径算法的使用,但是还是有很多的不足,许多Java方法并不是很会。