地铁换乘计费系统(计应192陈莉莉第三组)

psp个人开发流程:

PSP阶段

预估时间

实际所用时间

计划

 13

11

  • 明确相关需求和其他因素,估计每个阶段的时间成本

 13

11

开发

91

96

  • 需求分析

10

8

  • 生成设计文档

 8

 10

  • 设计审复(和同事审核设计文档)

 12

10

  • 代码规范(为目前开发制定合适的规范)

 8

 6

  • 具体设计

 11

 15

  • 具体编码

 19

 25

  • 代码复审

 10

 10

  • 测试(自测,修改代码,提交修改)

13

12

报告

 16

12

  • 测试报告

5

 4

  • 计算工作量

5

 3

  • 事后总结,并提出过程改进计划

 6

 5

总共花费时间

120

107

计划:

明确需求会和其他相关因素,计算时间成本

开发:

需求分析:

起点到终点之间经过的车站数量

具体设计:

已知2条地铁线路,其中A为环线,B为东西向线路,线路都是双向的。经过的站点名分别如下,两条线交叉的换乘点用T1、T2表示。编写程序,任意输入两个站点名称,输出乘坐地铁最少需要经过的车站数量(含输入的起点和终点,换乘站点只计算一次)。

地铁线A(环线)经过车站:A1 A2 A3 A4 A5 A6 A7 A8 A9 T1 A10 A11 A12 A13 T2 A14 A15 A16 A17 A18

地铁线B(直线)经过车站:B1 B2 B3 B4 B5 T1 B6 B7 B8 B9 B10 T2 B11 B12 B13 B14 B15

具体代码和代码规范:

  1 package com.patrick.bishi;
  2 
  3 import java.util.HashSet;
  4 
  5 import java.util.LinkedList;
  6 
  7 import java.util.Scanner;
  8 
  9 import java.util.Set;
 10 
 11 /**
 12 
 13 * 获取两条地铁线上两点间的最短站点数
 14 
 15 *
 16 
 17 * @author patrick
 18 
 19 *
 20 
 21 */
 22 
 23 public class SubTrain {
 24 private static LinkedList subA = new LinkedList();
 25 
 26 private static LinkedList subB = new LinkedList();
 27 
 28 public static void main(String[] args) {
 29 String sa[] = { "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9",
 30 
 31 "T1", "A10", "A11", "A12", "A13", "T2", "A14", "A15", "A16",
 32 
 33 "A17", "A18" };
 34 
 35 String sb[] = { "B1", "B2", "B3", "B4", "B5", "T1", "B6", "B7", "B8",
 36 
 37 "B9", "B10", "T2", "B11", "B12", "B13", "B14", "B15" };
 38 
 39 Set plots = new HashSet();
 40 
 41 for (String t : sa) {
 42 plots.add(t);
 43 
 44 subA.add(t);
 45 
 46 }
 47 
 48 for (String t : sb) {
 49 plots.add(t);
 50 
 51 subB.add(t);
 52 
 53 }
 54 
 55 Scanner in = new Scanner(System.in);
 56 
 57 String input = in.nextLine();
 58 
 59 String trail[] = input.split("\\s");
 60 
 61 String src = trail[0];
 62 
 63 String dst = trail[1];
 64 
 65 if (!plots.contains(src) || !plots.contains(dst)) {
 66 System.err.println("no these plot!");
 67 
 68 return;
 69 
 70 }
 71 
 72 int len = getDistance(src, dst);
 73 
 74 System.out.printf("The shortest distance between %s and %s is %d", src,
 75 
 76 dst, len);
 77 
 78 }
 79 
 80 // 经过两个换乘站点后的距离
 81 
 82 public static int getDist(String src, String dst) {
 83 int len = 0;
 84 
 85 int at1t2 = getDistOne("T1", "T2");
 86 
 87 int bt1t2 = subB.indexOf("T2") - subB.indexOf("T1") + 1;
 88 
 89 int a = 0;
 90 
 91 if (src.equals("T1")) {
 92 a = getDistOne(dst, "T2");
 93 
 94 len = a + bt1t2 - 1;// two part must more 1
 95 
 96 } else if (src.equals("T2")) {
 97 a = getDistOne(dst, "T1");
 98 
 99 len = a + bt1t2 - 1;
100 
101 } else if (dst.equals("T1")) {
102 a = getDistOne(src, "T2");
103 
104 len = a + at1t2 - 1;
105 
106 } else if (dst.equals("T2")) {
107 a = getDistOne(src, "T1");
108 
109 len = a + at1t2 - 1;
110 
111 }
112 
113 return len;
114 
115 }
116 
117 // 获得一个链表上的两个元素的最短距离
118 
119 private static int getDistOne(String src, String dst) {
120 int aPre, aBack, aLen, len, aPos, bPos;
121 
122 aPre = aBack = aLen = len = 0;
123 
124 aLen = subA.size();
125 
126 if ("T1".equals(src) && "T2".equals(dst)) {
127 int a = subA.indexOf("T1");
128 
129 int b = subA.indexOf("T2");
130 
131 int at1t2 = (b - a) > (a + aLen - b) ? (a + aLen - b) : (b - a);
132 
133 int bt1t2 = subB.indexOf("T2") - subB.indexOf("T1");
134 
135 len = at1t2 > bt1t2 ? bt1t2 : at1t2;
136 
137 } else if (subA.contains(src) && subA.contains(dst)) {
138 aPos = subA.indexOf(src);
139 
140 bPos = subA.indexOf(dst);
141 
142 if (aPos > bPos) {
143 aBack = aPos - bPos;
144 
145 aPre = aLen - aPos + bPos;
146 
147 len = aBack > aPre ? aPre : aBack;
148 
149 } else {
150 aPre = bPos - aPos;
151 
152 aBack = aLen - bPos + aPos;
153 
154 len = aBack > aPre ? aPre : aBack;
155 
156 }
157 
158 } else if (subB.contains(src) && subB.contains(dst)) {
159 aPos = subB.indexOf(src);
160 
161 bPos = subB.indexOf(dst);
162 
163 len = aPos > bPos ? (aPos - bPos) : (bPos - aPos);
164 
165 } else {
166 System.err.println("Wrong!");
167 
168 }
169 
170 return len + 1;
171 
172 }
173 
174 public static int getDistance(String src, String dst) {
175 int aPre, aBack, len, aLen;
176 
177 aPre = aBack = len = aLen = 0;
178 
179 aLen = subA.size();
180 
181 int a = subA.indexOf("T1");
182 
183 int b = subA.indexOf("T2");
184 
185 int at1t2 = (b - a) > (a + aLen - b) ? (a + aLen - b) : (b - a);
186 
187 int bt1t2 = subB.indexOf("T2") - subB.indexOf("T1");
188 
189 if ((subA.contains(src) && subA.contains(dst))
190 
191 || (subB.contains(src) && subB.contains(dst))) {
192 len = getDistOne(src, dst);
193 
194 if (src.equals("T1") || src.equals("T2") || dst.equals("T1")
195 
196 || dst.equals("T2")) {
197 int t = getDist(src, dst);
198 
199 len = len > t ? t : len;
200 
201 }
202 
203 } else {
204 int at1 = getDist(src, "T1");
205 
206 int at2 = getDist(src, "T2");
207 
208 int bt1 = getDist(dst, "T1");
209 
210 int bt2 = getDist(dst, "T2");
211 
212 aPre = at1 + bt1 - 1;
213 
214 aBack = at2 + bt2 - 1;
215 
216 len = aBack > aPre ? aPre : aBack;
217 
218 aPre = at1t2 + at1 + bt2 - 2;
219 
220 aBack = bt1t2 + at2 + bt1 - 2;
221 
222 int tmp = aBack > aPre ? aPre : aBack;
223 
224 len = len > tmp ? tmp : len;
225 
226 }
227 
228 return len;
229 
230 }
231 
232 }
233 
234 通用乘地铁方案的实现(最短距离利用Dijkstra算法):
235 
236 package com.patrick.bishi;
237 
238 import java.util.ArrayList;
239 
240 import java.util.List;
241 
242 import java.util.Scanner;
243 
244 /**
245 
246 * 地铁中任意两点的最有路径
247 
248 *
249 
250 * @author patrick
251 
252 *
253 
254 */
255 
256 public class SubTrainMap {
257 protected int[][] subTrainMatrix; // 图的邻接矩阵,用二维数组表示
258 
259 private static final int MAX_WEIGHT = 99; // 设置最大权值,设置成常量
260 
261 private int[] dist;
262 
263 private List vertex;// 按顺序保存顶点s
264 
265 private List edges;
266 
267 public int[][] getSubTrainMatrix() {
268 return subTrainMatrix;
269 
270 }
271 
272 public void setVertex(List vertices) {
273 this.vertex = vertices;
274 
275 }
276 
277 public List getVertex() {
278 return vertex;
279 
280 }
281 
282 public List getEdges() {
283 return edges;
284 
285 }
286 
287 public int getVertexSize() {
288 return this.vertex.size();
289 
290 }
291 
292 public int vertexCount() {
293 return subTrainMatrix.length;
294 
295 }
296 
297 @Override
298 
299 public String toString() {
300 String str = "邻接矩阵:\n";
301 
302 int n = subTrainMatrix.length;
303 
304 for (int i = 0; i < n; i++) {
305 for (int j = 0; j < n; j++)
306 
307 str += this.subTrainMatrix[i][j] == MAX_WEIGHT ? " $" : " "
308 
309 + this.subTrainMatrix[i][j];
310 
311 str += "\n";
312 
313 }
314 
315 return str;
316 
317 }
318 
319 public SubTrainMap(int size) {
320 this.vertex = new ArrayList();
321 
322 this.subTrainMatrix = new int[size][size];
323 
324 this.dist = new int[size];
325 
326 for (int i = 0; i < size; i++) { // 初始化邻接矩阵
327 
328 for (int j = 0; j < size; j++) {
329 this.subTrainMatrix[i][j] = (i == j) ? 0 : MAX_WEIGHT;// 无向图
330 
331 }
332 
333 }
334 
335 }
336 
337 public SubTrainMap(List vertices) {
338 this.vertex = vertices;
339 
340 int size = getVertexSize();
341 
342 this.subTrainMatrix = new int[size][size];
343 
344 this.dist = new int[size];
345 
346 for (int i = 0; i < size; i++) { // 初始化邻接矩阵
347 
348 for (int j = 0; j < size; j++) {
349 this.subTrainMatrix[i][j] = (i == j) ? 0 : MAX_WEIGHT;
350 
351 }
352 
353 }
354 
355 }
356 
357 /**
358 
359 * 获得顶点在数组中的位置
360 
361 *
362 
363 * @param s
364 
365 * @return
366 
367 */
368 
369 public int getPosInvertex(T s) {
370 return vertex.indexOf(s);
371 
372 }
373 
374 public int getWeight(T start, T stop) {
375 int i = getPosInvertex(start);
376 
377 int j = getPosInvertex(stop);
378 
379 return this.subTrainMatrix[i][j];
380 
381 } // 返边的权值
382 
383 public void insertEdge(T start, T stop, int weight) { // 插入一条边
384 
385 int n = subTrainMatrix.length;
386 
387 int i = getPosInvertex(start);
388 
389 int j = getPosInvertex(stop);
390 
391 if (i >= 0 && i < n && j >= 0 && j < n
392 
393 && this.subTrainMatrix[i][j] == MAX_WEIGHT && i != j) {
394 this.subTrainMatrix[i][j] = weight;
395 
396 this.subTrainMatrix[j][i] = weight;
397 
398 }
399 
400 }
401 
402 public void addEdge(T start, T dest, int weight) {
403 this.insertEdge(start, dest, weight);
404 
405 }
406 
407 public void removeEdge(String start, String stop) { // 删除一条边
408 
409 int i = vertex.indexOf(start);
410 
411 int j = vertex.indexOf(stop);
412 
413 if (i >= 0 && i < vertexCount() && j >= 0 && j < vertexCount()
414 
415 && i != j)
416 
417 this.subTrainMatrix[i][j] = MAX_WEIGHT;
418 
419 }
420 
421 @SuppressWarnings("unused")
422 
423 private static void newGraph() {
424 List vertices = new ArrayList();
425 
426 vertices.add("A");
427 
428 vertices.add("B");
429 
430 vertices.add("C");
431 
432 vertices.add("D");
433 
434 vertices.add("E");
435 
436 graph = new SubTrainMap(vertices);
437 
438 graph.addEdge("A", "B", 5);
439 
440 graph.addEdge("A", "D", 2);
441 
442 graph.addEdge("B", "C", 7);
443 
444 graph.addEdge("B", "D", 6);
445 
446 graph.addEdge("C", "D", 8);
447 
448 graph.addEdge("C", "E", 3);
449 
450 graph.addEdge("D", "E", 9);
451 
452 }
453 
454 private static SubTrainMap graph;
455 
456 /** 打印顶点之间的距离 */
457 
458 public void printL(int[][] a) {
459 for (int i = 0; i < a.length; i++) {
460 for (int j = 0; j < a.length; j++) {
461 System.out.printf("%4d", a[i][j]);
462 
463 }
464 
465 System.out.println();
466 
467 }
468 
469 }
470 
471 public static void main(String[] args) {
472 // newGraph();
473 
474 String sa[] = { "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9",
475 
476 "T1", "A10", "A11", "A12", "A13", "T2", "A14", "A15", "A16",
477 
478 "A17", "A18" };
479 
480 String sb[] = { "B1", "B2", "B3", "B4", "B5", "T1", "B6", "B7", "B8",
481 
482 "B9", "B10", "T2", "B11", "B12", "B13", "B14", "B15" };
483 
484 List vertices = new ArrayList();
485 
486 for (String t : sa) {
487 if (!vertices.contains(t)) {
488 vertices.add(t);
489 
490 }
491 
492 }
493 
494 for (String t : sb) {
495 if (!vertices.contains(t)) {
496 vertices.add(t);
497 
498 }
499 
500 }
501 
502 graph = new SubTrainMap(vertices);
503 
504 for (int i = 0; i < sa.length - 1; i++)
505 
506 graph.addEdge(sa[i], sa[i + 1], 1);
507 
508 graph.addEdge(sa[0], sa[sa.length - 1], 1);
509 
510 for (int i = 0; i < sb.length - 1; i++)
511 
512 graph.addEdge(sb[i], sb[i + 1], 1);
513 
514 Scanner in = new Scanner(System.in);
515 
516 System.out.println("请输入起始站点:");
517 
518 String start = in.nextLine().trim();
519 
520 System.out.println("请输入目标站点:");
521 
522 String stop = in.nextLine().trim();
523 
524 if (!graph.vertex.contains(start) || !graph.vertex.contains(stop)) {
525 System.out.println("地图中不包含该站点!");
526 
527 return;
528 
529 }
530 
531 int len = graph.find(start, stop) + 1;// 包含自身站点
532 
533 System.out.println(start + " -> " + stop + " 经过的站点数为: " + len);
534 
535 }
536 
537 public int find(T start, T stop) {
538 int startPos = getPosInvertex(start);
539 
540 int stopPos = getPosInvertex(stop);
541 
542 if (startPos < 0 || startPos > getVertexSize())
543 
544 return MAX_WEIGHT;
545 
546 String[] path = dijkstra(startPos);
547 
548 System.out.println("从" + start + "出发到" + stop + "的最短路径为:"
549 
550 + path[stopPos]);
551 
552 return dist[stopPos];
553 
554 }
555 
556 // 单元最短路径问题的Dijkstra算法
557 
558 private String[] dijkstra(int vertex) {
559 int n = dist.length - 1;
560 
561 String[] path = new String[n + 1]; // 存放从start到其他各点的最短路径的字符串表示
562 
563 for (int i = 0; i <= n; i++)
564 
565 path[i] = new String(this.vertex.get(vertex) + "-->"
566 
567 + this.vertex.get(i));
568 
569 boolean[] visited = new boolean[n + 1];
570 
571 // 初始化
572 
573 for (int i = 0; i <= n; i++) {
574 dist[i] = subTrainMatrix[vertex][i];// 到各个顶点的距离,根据顶点v的数组初始化
575 
576 visited[i] = false;// 初始化访问过的节点,当然都没有访问过
577 
578 }
579 
580 dist[vertex] = 0;
581 
582 visited[vertex] = true;
583 
584 for (int i = 1; i <= n; i++) {// 将所有的节点都访问到
585 
586 int temp = MAX_WEIGHT;
587 
588 int visiting = vertex;
589 
590 for (int j = 0; j <= n; j++) {
591 if ((!visited[j]) && (dist[j] < temp)) {
592 temp = dist[j];
593 
594 visiting = j;
595 
596 }
597 
598 }
599 
600 visited[visiting] = true; // 将距离最近的节点加入已访问列表中
601 
602 for (int j = 0; j <= n; j++) {// 重新计算其他节点到指定顶点的距离
603 
604 if (visited[j]) {
605 continue;
606 
607 }
608 
609 int newdist = dist[visiting] + subTrainMatrix[visiting][j];// 新路径长度,经过visiting节点的路径
610 
611 if (newdist < dist[j]) {
612 // dist[j] 变短
613 
614 dist[j] = newdist;
615 
616 path[j] = path[visiting] + "-->" + this.vertex.get(j);
617 
618 }
619 
620 }// update all new distance
621 
622 }// visite all nodes
623 
624 // for (int i = 0; i <= n; i++)
625 
626 // System.out.println("从" + vertex + "出发到" + i + "的最短路径为:" + path[i]);
627 
628 // System.out.println("=====================================");
629 
630 return path;
631 
632 }
633 
634 /**
635 
636 * 图的边
637 
638 *
639 
640 * @author patrick
641 
642 *
643 
644 */
645 
646 class Edge {
647 private T start, dest;
648 
649 private int weight;
650 
651 public Edge() {
652 }
653 
654 public Edge(T start, T dest, int weight) {
655 this.start = start;
656 
657 this.dest = dest;
658 
659 this.weight = weight;
660 
661 }
662 
663 public String toString() {
664 return "(" + start + "," + dest + "," + weight + ")";
665 
666 }
667 
668 }
669 
670 }

代码复审:

编写代码不可能一次就成功,需要使用debug进行检查运行,对出现的错误及时进行修改,对代码进行完善。

总结:

由于自身基础薄弱,知识能力有限,所以本次项目对于自己来说还是有些困难的,所以和他人一起协作才完成了这个项目,这也让我明白了结对协作的重要性,以后定加倍努力学习,希望自己在这条路上能够走的更远

 

posted @ 2021-04-11 19:13  优秀的优  阅读(212)  评论(0编辑  收藏  举报