一.问题定义
基本信息查询以及校园导游咨询
二.模块拆分
一、参赛队伍信息管理模块
1.管理各参赛队的基本信息(包含参赛队编号,参赛作品名称,参赛学校,赛事类别,参赛者,指导老师),赛事类别共11项(参见大赛官网jsjds.blcu.edu.cn);
2.实现对参赛队伍信息的增加、删除、修改操作。
二、参赛队伍信息查询模块
1.从team.txt中读取参赛队伍的基本信息,实现基于二叉排序树的查找;
2.根据输入的参赛队编号,输出该赛事类别对应的基本信息(参赛作品名称、参赛学校、赛事类别、参赛者和指导老师信息),同时,输出查找成功时的平均查找长度ASL;
3.如果查找失败,输出“查找失败!”。
三、参赛队伍信息按学校或赛事类别查询模块
1.可以根据参赛学校名称或赛事类别查询参赛团队;
2.输出参赛团队按赛事类别有序输出,排序算法可从选择排序、插入排序、希尔排序、归并排序、堆排序中任意选择,并为选择算法的原因做出说明。
四、省赛现场决赛叫号系统模块
1.所有参赛队按赛事组织文件中的赛事类别分到9个决赛室;
2.决赛室按顺序叫号,被叫号参赛队进场;
3.比赛结束后,下一参赛队才能进赛场。
五、校园导游与路径导航模块
1.为参赛者提供赛地的校园导游程序;
2.为参赛者提供各种路径导航的查询服务;
3.提供不少于10个目标地的导航;
4.可以为参赛者提供校园地图中任意目标地相关信息的查询;
5.可以提供任意两个目标地之间的一条最短路径的导航查询。
三.概要设计
1.参赛队伍信息管理模块:
实现添加、删除、修改参赛队伍信息的功能,并将参赛队伍信息存储在文件中。
2.参赛队伍信息查询模块:
从文件中读取参赛队伍信息到二叉排序树中,实现基于二叉排序树的查找功能,并输出查找结果和平均查找长度ASL。
sc = new Scanner(System.in);
switch (sc.nextInt()) {
case 1:
System.out.println("输入你想要查询的队伍的编号");
int num = sc.nextInt();
if (teams.search(num) == null) System.out.println("未查询到该队伍");
else System.out.println(teams.search(num));
break;
case 2:
System.out.println("输入你想要增加队伍的基本信息");
System.out.println("输入队伍的编号");
int number = sc.nextInt();
if (teams.search(number) != null) {
System.out.println("已存在该队伍编号");
break;
}
System.out.println("输入参赛作品名称");
String workName = sc.next();
System.out.println("输入参赛学校");
String school = sc.next();
System.out.println("输入赛事类别");
String cate = sc.next();
System.out.println("输入参赛者姓名");
String name = sc.next();
System.out.println("输入指导老师姓名");
String teacher = sc.next();
Team newTeam = new Team(number, workName, school, cate, name, teacher);
teams.insert(newTeam);
break;
case 3:
System.out.println("输入你想删除队伍的编号");
int delNum = sc.nextInt();
teams.delNode(delNum);
break;
case 4:
System.out.println("输入你想修改队伍的编号");
int UpdateNum = sc.nextInt();
if (teams.search(UpdateNum) == null) {
System.out.println("该队伍不存在");
break;
}
System.out.println("输入你想修改的队伍信息");
System.out.println("输入参赛作品名称");
String newWorkName = sc.next();
System.out.println("输入参赛学校");
String newSchool = sc.next();
System.out.println("输入赛事类别");
String newCate = sc.next();
System.out.println("输入参赛者姓名");
String newName = sc.next();
System.out.println("输入指导老师姓名");
String newTeacher = sc.next();
System.out.println();
teams.update(UpdateNum, newWorkName, newSchool, newCate, newName, newTeacher);
System.out.println("修改成功");
break;
case 5:
System.out.println("输入你想查询的学校名称");
String searchSchool = sc.next();
teams.searchAsSchool(searchSchool);
break;
case 6:
n = 0;
break;
default:
System.out.println("请重新输入");
}
}
break;
3.参赛队伍信息按学校或赛事类别查询模块:
实现按参赛学校或赛事类别查询参赛团队的功能,并通过选择排序、插入排序、希尔排序、归并排序、堆排序等算法之一进行排序。
4.省赛现场决赛叫号系统模块:
将参赛队伍按照赛事类别分成9个组,实现决赛叫号系统,按照顺序叫号,被叫号参赛队伍进场,比赛结束后,下一参赛队才能进赛场。
public class Call {
public void create(String name,int start,int end) {
MyThread t = new MyThread(name,start,end);
t.start();
}
public static void call(){
Call call=new Call();
call.create("第一决赛室",0,45);
Call call1=new Call();
call1.create("第二决赛室",45,90);
Call call2=new Call();
call2.create("第三决赛室",90,135);
Call call3=new Call();
call3.create("第四决赛室",135,180);
Call call4=new Call();
call4.create("第五决赛室",180,225);
Call call5=new Call();
call5.create("第六决赛室",225,270);
Call call6=new Call();
call6.create("第七决赛室",270,315);
Call call7=new Call();
call7.create("第八决赛室",315,360);
Call call8=new Call();
call8.create("第九决赛室",360,398);
}
}
class MyThread extends Thread {
int start;
int end;
public Teams teams;
Queue queue;
public MyThread() {
}
public MyThread(String name, int start, int end) {
super(name);
teams = new Teams();
queue = new Queue(end-start);
this.start = start;
this.end = end;
for (int i = start; i < end; i++) {
queue.add(teams.teamList.get(i));
}
}
@Override
public void run() {
while (queue.peek() != null) {
System.out.println("请编号" + queue.peek().number + "队伍前往" + getName() + "进行比赛");
try {
currentThread().sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("编号" + queue.poll().number + "队伍比赛结束");
this.yield();
}
}
}
5.校园导游与路径导航模块:
实现校园导游程序和路径导航查询服务,提供不少于10个目标地的导航,可以为参赛者提供校园地图中任意目标地相关信息的查询,可以提供任意两个目标地之间的一条最短路径的导航查询。
public class Map {
static final int N = 1024;
private ArrayList<Building> vertexList;//存储定点集合
private int[][] edges;//存储对应的邻接矩阵
private int[][] pre;//保存到达目标顶点的前驱顶点
//显示图对应的矩阵
public void showGraph() {
for (int[] link : edges) {
System.out.println(Arrays.toString(link));
}
}
//初始化
public Map() {
int n = 10;
//初始化地图
edges = new int[n][n];
vertexList = new ArrayList<Building>(n);
for (int i = 0; i < edges.length; i++) {
for (int j = 0; j < edges[i].length; j++) {
edges[i][j] = N;
}
}
this.pre = new int[10][10];//对pre数组初始化,注意存放的是前驱顶点的下标
for (int i = 0; i < 10; i++) {
Arrays.fill(pre[i], i);
}
Building b1 = new Building("3号组团", 1, "西区学生休息的地方");
Building b2 = new Building("西苑食堂", 2, "西区学生吃饭的地方");
Building b3 = new Building("明德园", 3, "西区学生玩乐的地方");
Building b4 = new Building("文体中心", 4, "西区学生做核酸的地方");
Building b5 = new Building("西操场", 5, "西区学生运动的地方");
Building b6 = new Building("文理大楼", 6, "全校学生学习的地方");
Building b7 = new Building("行政大楼", 7, "行政的地方");
Building b8 = new Building("求索园", 8, "东区学生玩乐的地方");
Building b9 = new Building("东苑食堂", 9, "东区学生吃饭的地方");
Building b10 = new Building("图书馆", 10, "学生自习的地方");
//在地图中添加节点
this.insertVertex(b1);
this.insertVertex(b2);
this.insertVertex(b3);
this.insertVertex(b4);
this.insertVertex(b5);
this.insertVertex(b6);
this.insertVertex(b7);
this.insertVertex(b8);
this.insertVertex(b9);
this.insertVertex(b10);
//在地图中添加边
this.insertEdge(b1, b2, 100);
this.insertEdge(b1, b4, 200);
this.insertEdge(b2, b3, 80);
this.insertEdge(b2, b4, 150);
this.insertEdge(b3, b5, 120);
this.insertEdge(b3, b6, 110);
this.insertEdge(b4, b5, 50);
this.insertEdge(b5, b8, 150);
this.insertEdge(b5, b9, 230);
this.insertEdge(b6, b7, 80);
this.insertEdge(b6, b8, 60);
this.insertEdge(b7, b10, 100);
this.insertEdge(b8, b9, 90);
this.insertEdge(b8, b10, 70);
this.insertEdge(b9, b10, 50);
}
//显示pre数组和dis数组
public void show(int code1, int code2) {
if (code1==-1||code2==1){
System.out.println("输入有误,请重新输入");
return;
}
System.out.println( vertexList.get(code1 - 1).name + "到" + vertexList.get(code2 - 1).name
+ "的最短距离是" + edges[code1-1][code2-1] );
}
public void floyd() {
int len = 0;
for (int k = 0; k < edges.length; k++) {
for (int i = 0; i < edges.length; i++) {
for (int j = 0; j < edges.length; j++) {
len = edges[i][k] + edges[k][j];//从i出发 经过k 到达j顶点距离
if (len < edges[i][j]) {
edges[i][j] = len;
pre[i][j] = pre[k][j];//更新前驱结点
}
}
}
}
}
//插入节点
public void insertVertex(Building building) {
vertexList.add(building);
}
public void insertEdge(Building b1, Building b2, int weight) {
edges[b1.code - 1][b2.code - 1] = weight;
edges[b2.code - 1][b1.code - 1] = weight;
}
//根据code查找代码
public void showBuilding(int i) {
for (int j = 0; j < vertexList.size(); j++) {
if (vertexList.get(j).code == i) {
Building target = vertexList.get(j);
System.out.println(target);
return;
}
}
System.out.println("未找到该建筑");
}
public void showBuilding(String name) {
for (int j = 0; j < vertexList.size(); j++) {
if (vertexList.get(j).name.equals(name)) {
Building target = vertexList.get(j);
System.out.println(target);
return;
}
}
System.out.println("未找到该建筑");
}
public void list(){
vertexList.forEach(System.out::println);
}
public int getCodeByName(String name){
int n=-1;
for (int j = 0; j < vertexList.size(); j++) {
if (vertexList.get(j).name.equals(name)) {
n= vertexList.get(j).code;
break;
}
}
return n;
}
}
class Building {
String name;
int code;
String description;
public Building() {
}
public Building(String name, int code, String description) {
this.name = name;
this.code = code;
this.description = description;
}
@Override
public String toString() {
return "Building{" +
"name='" + name + '\'' +
", code=" + code +
", description='" + description + '\'' +
'}';
}
}
江苏科技大学长山校区为例,图例如下:
可制作如下示意图。