1.问题定义
计算机设计大赛赛事管理系统、决赛叫号系统、校园导游程序
2.问题分析
2.1计算机设计大赛赛事管理系统
2.1.1能够管理各参赛队的基本信息(包含参赛队编号,参赛作品名称,参赛学校,赛事类别,参赛者,指导老师),赛事类别共11项;包括增加、删除、修改参赛队伍的信息。
可以建立一个队伍类Team,用来存储参赛队伍信息,包括:参赛队编号,参赛作品名称,参赛学校,赛事类别,参赛者,指导老师。接下来定义一个类TeamManager来管理赛队伍的基本信息,包括对进行信息的增删改。
通过调用 addTeam() 方法可以增加一个参赛队伍,通过调用 deleteTeam() 方法可以删除一个参赛队伍,通过调用 updateTeam() 方法可以修改参赛队伍的信息。
2.1.2从team.txt中读取参赛队伍的基本信息,实现基于二叉排序树的查找。根据提示输入参赛队编号,若查找成功,输出该赛事类别对应的基本信息(参赛作品名称、参赛学校、赛事类别、参赛者和指导老师信息),同时,输出查找成功时的平均查找长度ASL;否则,输出“查找失败!”。
定义一个初始化参赛队伍列表的方法,它的作用是从一个文件中读取队伍信息,并将读取到的信息转化为 Team 对象并加入到一个列表中。在这个方法中,使用了 Java 标准库的 BufferedReader 类和 FileInputStream 类来读取文件内容。
二叉排序树的查找是从根结点开始的,沿某个分支逐层向下进行比较的过程。若二叉排序树非空,则将给定值与根结点的关键字比较,若相等,则查找成功;若不等,则当根结点的关键字值大于给定关键字值时,在根结点的左子树中查找;否则在根结点的右子树中查找。利用 BFS(广度优先搜索)算法计算平均查找长度 ASL 。BFS 可以按照结点的层次依次访问节点,从而可以减少遍历的深度。另外,BFS 遍历时可以使用队列来进行实现,对于平均查找长度的计算,队列数据结构可以更好的体现这种计算逐层进行的特点。
2.1.3能够提供按参赛学校查询参赛团队(或根据赛事类别查询参赛团队),即,根据提示输入参赛学校名称(赛事类别),若查找成功,输出该学校参赛的(该赛事类别的)所有团队的基本信息,输出的参赛团队按赛事类别有序输出。(排序算法可从选择排序、插入排序、希尔排序、归并排序、堆排序中任意选择,并为选择算法的原因做出说明。)
查询参赛队伍信息的方法通常需要先对整个数据集进行遍历,并将符合条件的对象提取出来,存放在一个集合中。然后对这个集合进行排序,并输出查找到的结果。
插入排序算法非常适合针对小规模数据集进行排序的场景,这也是这个方法使用插入排序的原因之一。
2.2决赛叫号系统
为省赛现场设计一个决赛叫号系统。所有参赛队按赛事组织文件中的赛事类别分到9个决赛室,决赛室按顺序叫号,被叫号参赛队进场,比赛结束后,下一参赛队才能进赛场。请模拟决赛叫号系统,演示省赛现场各决赛室的参赛队进场情况。(模拟时,要能直观展示叫号顺序与进场秩序一致)
需要设计一个系统,可以根据不同的赛事类别分配参赛队到相应的决赛室,按顺序叫号,控制参赛队进场和出场的顺序。定义一个Room类,实现分配编号、入队、模拟叫号的功能。
2.3校园导游程序
赛事系统为参赛者提供赛地的校园导游程序,为参赛者提供各种路径导航的查询服务。以我校长山校区提供比赛场地为例,(请为参赛者提供不少于10个目标地的导航。可为参赛者提供校园地图中任意目标地(建筑物)相关信息的查询;提供任意两个目标地(建筑物)的导航查询,即查询任意两个目的地(建筑物)之间的一条最短路径。
校园的道路是双向通行的,可设校园平面图是一个无向网,顶点和边均含有相关信息。
查询任意两个目的地(建筑物)之间的一条最短路径,是一个图论问题,即无向图。对于图的存储结构而言,图中各个目标地的存储结构有邻接表和邻接矩阵两种存储结构,考虑到顶点数少于50个,所以邻接表和邻接矩阵的复杂度相同,则选用邻接矩阵。
定义一个建筑物类,包含建筑物名称和描述。
定义了一个 Path 类,用于描述地图中两个建筑物之间的连接边,包括边的起点 from、终点 to 和距离 distance 三个属性。
定义校园地图类,包含了地图中的建筑物信息和相邻建筑物之间的连接路径信息。
为了实现导航查询:获取从起点到终点的最短路径和总距离。可以使用 Dijkstra 算法,设计一个方法 findShortestPath(String start, String end) 接受起始位置和目标位置两个参数,返回从起始位置到目标位置的最短路径列表。Dijkstra 算法是一种贪心算法,可以求出最短路径。通过使用哈希表和优先队列,可以有效地减小查找时间,提高了算法效率。
3.概要设计
3.1计算机设计大赛赛事管理系统
- 实验基于java,先完成参赛队基本信息和二叉排序树的定义
public class Team {
//参赛队伍编号
private String teamNumber;
// 参赛作品名称
private String projectName;
// 参赛学校
private String school;
// 赛事类别
private String category;
// 参赛者
private String participants;
// 指导老师
private String instructor;
// 节点内部类
static class Node {
//编号
double key;
Team team;
Node left, right;
Node(double key, Team team) {
this.key = key;
this.team = team;
left = right = null;
}
}
//根节点
Node root;
- 主要函数
public TeamManager() {
this.teams = new ArrayList<>();
}
// 从txt文件中读取队伍信息并存储到列表中
public void loadTeamsFromFile(String filePath,String charset ) {
CommonUtils.initTeamsList(teams,filePath,charset);
}
public void addTeam(Team team,String filePath) {
teams.add(team);
CommonUtils.saveTeamsToFile(teams,filePath);
}
public void deleteTeam(String teamNum,String filePath) {
// 方法说明 判断是否满足后面的添加如果满足就进行删除 参数传入的是Lambda表达式
teams.removeIf(team -> team.getTeamNumber().equals(teamNum));
CommonUtils.saveTeamsToFile(teams,filePath);
}
public void updateTeam(Team updateTeam,String filePath) {
for (Team team : teams) {
if (team.getTeamNumber().equals(updateTeam.getTeamNumber())) {
if (updateTeam.getCategory()!=null){
team.setCategory(updateTeam.getCategory());
}
if (updateTeam.getSchool()!=null){
team.setSchool(updateTeam.getSchool());
}
if (updateTeam.getProjectName()!=null){
team.setProjectName(updateTeam.getProjectName());
}
if (updateTeam.getParticipants()!=null){
team.setParticipants(updateTeam.getParticipants());
}
if (updateTeam.getInstructor()!=null){
team.setInstructor(updateTeam.getInstructor());
}
CommonUtils.saveTeamsToFile(teams,filePath);
break;
}
}
}
// 查询并输出参赛团队信息的方法
public void queryTeamsBySchool(String school) {
List<Team> queriedTeams = new ArrayList<>();
// 遍历所有参赛队伍,找到符合赛事类别的参赛团队
for (Team team : teams) {
if (team.getSchool().contains(school)){
queriedTeams.add(team);
}
if (team.getSchool().equals(school)) {
queriedTeams.add(team);
}
}
// 使用插入排序对查询结果按赛事类别进行排序
for (int i = 1; i < queriedTeams.size(); i++) {
Team current = queriedTeams.get(i);
int j = i - 1;
while (j >= 0 && queriedTeams.get(j).getTeamNumber().compareTo(current.getTeamNumber()) > 0) {
queriedTeams.set(j + 1, queriedTeams.get(j));
j--;
}
queriedTeams.set(j + 1, current);
}
// 输出查询结果
if (queriedTeams.isEmpty()) {
System.out.println("未找到该赛事类别的参赛团队!");
} else {
for (Team team : queriedTeams) {
System.out.println("参赛编号:"+ team.getTeamNumber());
System.out.println("参赛作品名称:" + team.getProjectName());
System.out.println("参赛学校:" + team.getSchool());
System.out.println("赛事类别:" + team.getCategory());
System.out.println("参赛者:" + team.getParticipants());
System.out.println("指导教师:" + team.getInstructor());
System.out.println("---------------------------");
}
}
}
public List<Team> queryTeamsBySchoolNoPrint(String school){
List<Team> queriedTeams = new ArrayList<>();
// 遍历所有参赛队伍,找到符合参赛学校的参赛团队
for (Team team : teams) {
if (team.getCategory().equals(school)) {
queriedTeams.add(team);
}
}
// 使用插入排序对查询结果按参赛学校进行排序
for (int i = 1; i < queriedTeams.size(); i++) {
Team current = queriedTeams.get(i);
int j = i - 1;
while (j >= 0 && queriedTeams.get(j).getTeamNumber().compareTo(current.getTeamNumber()) > 0) {
queriedTeams.set(j + 1, queriedTeams.get(j));
j--;
}
queriedTeams.set(j + 1, current);
}
return queriedTeams;
}
public void printTeams() {
for (Team team : teams) {
System.out.println(team);
}
}
// 得到队伍列表
public List<Team> getTeams() {
return teams;
}
3.2决赛叫号系统
- 主要函数
public FinalsCallSystem(List<String> eventCategories) {
this.eventCategories = eventCategories;
this.rooms = new ArrayList<>();
}
// 初始化各个决赛室的队伍队列
public void initializeRooms(TeamManager teamManager) {
for (int i =0;i<eventCategories.size();i++){
String currentCategory = eventCategories.get(i);
Room room = new Room(currentCategory);
List<Team> teams = teamManager.queryTeamsBySchoolNoPrint(currentCategory);
room.setCompetitionTeams(teams);
rooms.add(room);
}
}
public void printRooms(){
for (Room room : rooms) {
room.printTeam();
}
}
public void startCompetition(){
List<Thread> threads = new ArrayList<>();
for (int i = 0; i <9; i++) {
Room room = rooms.get(i);
Thread thread = new Thread(room);
threads.add(thread);
}
// 启动所有决赛室的线程
for (Thread thread : threads) {
thread.start();
}
// 等待所有线程执行结束
for (Thread thread : threads) {
try {
thread.join();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
public static class TeamNode {
private Team team;
private TeamNode left;
private TeamNode right;
public TeamNode(Team team) {
this.team = team;
left = null;
right = null;
}
public Team getTeam() {
return team;
}
public void setTeam(Team team) {
this.team = team;
}
public TeamNode getLeft() {
return left;
}
public void setLeft(TeamNode left) {
this.left = left;
}
public TeamNode getRight() {
return right;
}
public void setRight(TeamNode right) {
this.right = right;
}
}
3.3校园导游程序
- 数据结构
// 建筑物类
public class Building {
private String name;
private String description;
public Building(String name, String description) {
this.name = name;
this.description = description;
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
private Map<String, Building> buildings;
private Map<String, List<Path>> adjacencyList;
public CampusMap() {
buildings = new HashMap<>();
adjacencyList = new HashMap<>();
}
// 添加建筑物
public void addBuilding(String name, String description) {
Building building = new Building(name, description);
buildings.put(name, building);
adjacencyList.put(name, new ArrayList<>());
}
// 添加路径连接
public void addPath(String from, String to, int distance) {
Path path = new Path(from, to, distance);
adjacencyList.get(from).add(path);
adjacencyList.get(to).add(path);
}
// 获取建筑物信息
public Building getBuilding(String name) {
return buildings.get(name);
}
// 导航查询:获取从起点到终点的最短路径和总距离
public List<String> findShortestPath(String start, String end) {
// 使用Dijkstra算法来查找最短路径
PriorityQueue<Path> queue = new PriorityQueue<>(Comparator.comparingInt(Path::getDistance));
Map<String, Integer> distanceMap = new HashMap<>();
Map<String, String> previous = new HashMap<>();
// 初始化距离
for (String building : buildings.keySet()) {
if (building.equals(start)) {
distanceMap.put(building, 0);
} else {
distanceMap.put(building, Integer.MAX_VALUE);
}
}
queue.add(new Path(null, start, 0));
while (!queue.isEmpty()) {
Path currentPath = queue.poll();
String current = currentPath.getTo();
if (current.equals(end)) {
// 已找到最短路径,回溯构建路径列表
List<String> path = new ArrayList<>();
String node = end;
int totalDistance = currentPath.getDistance();
while (node != null) {
path.add(0, node);
node = previous.get(node);
}
path.add(Integer.toString(totalDistance)); // 添加总距离
return path;
}
if (currentPath.getDistance() > distanceMap.get(current)) {
continue; // 已经存在更短路径,忽略当前路径
}
for (Path neighborPath : adjacencyList.get(current)) {
String neighbor = neighborPath.getFrom().equals(current) ? neighborPath.getTo() : neighborPath.getFrom();
int newDistance = distanceMap.get(current) + neighborPath.getDistance();
if (newDistance < distanceMap.get(neighbor)) {
distanceMap.put(neighbor, newDistance);
previous.put(neighbor, current);
queue.add(new Path(current, neighbor, newDistance));
}
}
}
return null; // 无法找到路径
}