目录
一、项目解析
本次课程设计要求协助中国大学生计算机设计大赛江苏省组委会,设计一款赛事管理系统,实现赛务相关的数据管理及信息服务,该系统能够为省级赛事管理解决以下问题:
(1)能够管理各参赛队的基本信息(包含参赛队编号,参赛作品名称,参赛学校,赛事类别,参赛者,指导老师),赛事类别共11项(参见大赛官网jsjds.blcu.edu.cn);包括增加、删除、修改参赛队伍的信息。
(2)从team.txt中读取参赛队伍的基本信息(如下图所示),实现基于二叉排序树的查找。根据提示输入参赛队编号,若查找成功,输出该赛事类别对应的基本信息(参赛作品名称、参赛学校、赛事类别、参赛者和指导老师信息),同时,输出查找成功时的平均查找长度ASL;否则,输出“查找失败!”。
(3)能够提供按参赛学校查询参赛团队(或根据赛事类别查询参赛团队),即,根据提示输入参赛学校名称(赛事类别),若查找成功,输出该学校参赛的(该赛事类别的)所有团队的基本信息,输出的参赛团队按赛事类别有序输出。(排序算法可从选择排序、插入排序、希尔排序、归并排序、堆排序中任意选择,并为选择算法的原因做出说明。)
(4)为省赛现场设计一个决赛叫号系统。所有参赛队按赛事组织文件中的赛事类别分到9个决赛室,决赛室按顺序叫号,被叫号参赛队进场,比赛结束后,下一参赛队才能进赛场。请模拟决赛叫号系统,演示省赛现场各决赛室的参赛队进场情况。(模拟时,要能直观展示叫号顺序与进场秩序一致)
(5)赛事系统为参赛者提供赛地的校园导游程序,为参赛者提供各种路径导航的查询服务。以我校长山校区提供比赛场地为例,(请为参赛者提供不少于10个目标地的导航。可为参赛者提供校园地图中任意目标地(建筑物)相关信息的查询;提供任意两个目标地(建筑物)的导航查询,即查询任意两个目的地(建筑物)之间的一条最短路径。
二、搭建框架
该项目是基于C++框架而成,通过使用二叉排序树来实现根据提示输入参赛队编号来查找参赛队伍的功能,使用快速排序来实现根据提示输入参赛学校名称来查找参赛队伍的功能。该系统功能选项多样,可以满足赛事管理的基本需求。
三、代码模块
信息初始化和构建二叉排序树
一、先使用结构体class类来创建队伍的基本信息对象,我先定义一个class对象Team来定义参赛队编号,参赛作品名称,参赛学校,赛事类别,参赛者,指导老师等基本信息,代码如下:
class Team {
private:
//基本信息
string TeamID; //参赛队编号
string workname; //参赛作品名称
string school; //参赛学校
string eventCate; //赛事类别 赛事类别共11项
string participants; //参赛者
string teachers; //指导老师
public:
//构造Team
Team() = default;
Team(string id, string Workname, string schoolname, string eventcatename, string Participant, string Teacher)
{
TeamID = id;
workname = Workname;
school = schoolname;
eventCate = eventcatename;
participants = Participant;
teachers = Teacher;
}
//输出参赛队编号
string getTeamID() {
return TeamID;
}
//输出作品名称
string getworkname() {
return workname;
}
string getschool() {
return school;
}
string geteventCate() {
return eventCate;
}
string getparticipants() {
return participants;
}
string getteachers() {
return teachers;
}
void insertTeamID(string id)
{
TeamID = id;
}
void insertworkname(string Workname)
{
workname = Workname;
}
void insertschool(string schoolname)
{
school = schoolname;
}
void inserteventCate(string eventcatename)
{
eventCate = eventcatename;
}
void insertparticipants(string Participant)
{
participants = Participant;
}
void insertteachers(string Teacher)
{
teachers = Teacher;
}
};
二、实现基于二叉排序树的查找,需要定义一个二叉排序树的结点结构体struct TreeNode,代码如下:
//二叉排序树的结点结构体
struct TreeNode {
Team team;
TreeNode* left;
TreeNode* right;
};
文件操作模块
打开文件后,使用getline函数,逐行读取,然后在使用while循环,如果遇到#就停止,然后将数据压入到vector类型的items当中,如果遇到了items当中的函数如果有六个元素,那么元素就一个一个插入到a当中,最后将a插入到teamsall和二叉排序树当中。
void insertinformation()
{
ifstream ifs;
string buf;
Team a;
teamsall.clear();
root = nullptr;
ifs.open("F:\\team.txt", ios::in);
if (!ifs.is_open())
{
cout << "文件打开失败" << endl;
}
else
{
while (std::getline(ifs, buf))
{
buf.erase(remove(buf.begin(), buf.end(), '\t'), buf.end());
string bufs;
vector<string> items;
stringstream ss(buf);
while (getline(ss, bufs, '#'))
{
items.push_back(bufs);
}
if (items.size() == 6)
{
a.insertTeamID(items[0]);
a.insertworkname(items[1]);
a.insertschool(items[2]);
a.inserteventCate(items[3]);
a.insertparticipants(items[4]);
a.insertteachers(items[5]);
teamsall.push_back(a);
insertTreeNode(root, a);
}
}
}
ifs.close();
}
队伍管理模块
//增加参赛队伍
void addteam(vector<Team>& team)
{
string id, project, schoolname, event, participants, teacher;
cout << "请输入参赛队编号:" << endl;
cin >> id;
cout << "请输入参赛作品名称:" << endl;
cin >> project;
cout << "请输入参赛参赛学校:" << endl;
cin >> schoolname;
cout << "请输入参赛的赛事类别:" << endl;
cin >> event;
cout << "请输入参赛者:" << endl;
cin >> participants;
cout << "请输入参赛的指导老师:" << endl;
cin >> teacher;
}
//删除参赛队伍
void deleteteam(vector<Team>& team, string id)
{
for (int i = 0; i < team.size(); i++)
{
if (team[i].getTeamID() == id)
{
team.erase(team.begin() + i);
cout << "删除成功!" << endl;
return;
}
}
cout << "里面没有这个参赛队伍" << endl;
}
//修改参赛队伍的信息
void reworkteam(vector<Team>& team, string id)
{
string id1; string project1, schoolname1, event1, participant1, Teacher1;
for (int i = 0; i < team.size(); i++)
{
if (team[i].getTeamID() == id)
{
cout << "请输入新参赛队编号:" << endl;
cin >> id1;
cout << "请输入新参赛作品名称:" << endl;
cin >> project1;
cout << "请输入新参赛参赛学校:" << endl;
cin >> schoolname1;
cout << "请输入新参赛的赛事类别:" << endl;
cin >> event1;
cout << "请输入新参赛者:" << endl;
cin >> participant1;
cout << "请输入新参赛的指导老师:" << endl;
cin >> Teacher1;
team[i].insertTeamID(id1);
team[i].insertschool(schoolname1);
team[i].insertworkname(project1);
team[i].inserteventCate(event1);
team[i].insertparticipants(participant1);
team[i].insertteachers(Teacher1);
}
}
cout << "里面没有这个参赛队伍,无法修改。" << endl;
}
队伍查询模块
1.根据提示输入参赛编号
//求平均查找长度
float ASL(TreeNode* node, string key, int depth) {
if (!node) return -1;
if (key == node->data.getTeamID()) return depth;
if (key < node->data.getTeamID())
return ASL(node->left, key, depth + 1);
else
return ASL(node->right, key, depth + 1);
}
//根据提示输入参赛学校编号
void searchid(TreeNode* node, string id)
{
long long c= std::atoi(id.c_str());
long long d= std::atoi(node->data.getTeamID().c_str());
if (node== NULL)
{
return;
}
if (d == c)
{
float a = ASL(root, id, 0);
cout <<"此时查找成功后的平均长度为:" << a << endl;
cout<< node->data.getTeamID() <<endl;
cout << node->data.getworkname() << endl;
cout << node->data.getschool() << endl;
cout << node->data.geteventCate() << endl;
cout << node->data.getparticipants() << endl;
cout << node->data.getteachers() << endl;
}
else if (c < d)
{
searchid(node->left,id);
}
else if (c > d)
{
searchid(node->right, id);
}
}
2.2.插入排序的查询输出(根据学校名称查询),我们按赛事类别有序输出结果,可以使用插入排序算法将参赛团队按赛事类别排序后输出结果。
void sortprint(vector<Team> team, string schoolname)
{
vector<Team> team1;
for (int i = 0; i < team.size(); i++)
{
if (team[i].getschool() == schoolname)
{
team1.push_back(team[i]);
}
}
for (int m = 0; m < team1.size(); m++)
{
long long a = std::atoi(team1[m].getTeamID().c_str());
teamID.push_back(a);
}
insertionSort(teamID);
for (int k = 0; k < teamID.size(); k++)
{
for (int m= 0; m < team1.size(); m++)
{
long long a = std::atoi(team1[m].getTeamID().c_str());
if (a == teamID[k])
{
cout << team1[m].getTeamID() << endl;
cout << team1[m].getworkname() << endl;
cout << team1[m].getschool() << endl;
cout << team1[m].geteventCate() << endl;
cout << team1[m].getparticipants() << endl;
cout << team1[m].getteachers() << endl;
}
}
}
}
决赛叫号系统
我们读取赛事组织文件中的参赛队信息,将其按照赛事类别分到各个决赛室的待叫号队列中。先选择赛区,看看是要输出哪个赛区。此时输出赛区的数字,然后按照输出赛区的叫号顺序,开始叫号后,一秒一秒地输出赛区的参赛队伍编号。
1.先在函数外面创建九个决赛区
vector<Team> a1;
vector<Team> a2;
vector<Team> a3;
vector<Team> a4;
vector<Team> a5;
vector<Team> a6;
vector<Team> a7;
vector<Team> a8;
vector<Team> a9;
2.把31个项目分别分成九个决赛区
void eventCate_separate(vector<Team> team)
{
vector<string> teameventCate;
for (int i = 0; i < team.size(); i++)
{
if (std::find(teameventCate.begin(), teameventCate.end(), team[i].geteventCate()) == teameventCate.end())
{
teameventCate.push_back(team[i].geteventCate());
}
}
for (int i = 0; i < teameventCate.size(); i++)
{
for (int m = 0; m < team.size(); m++)
{
if (i < 3)
{
if (teameventCate[i] ==team[m].geteventCate())
{
a1.push_back(team[m]);
}
}
if (i>=3&&i<=5)
{
if (teameventCate[i] == team[m].geteventCate())
{
a2.push_back(team[m]);
}
}
if (i >= 6 && i <= 8)
{
if (teameventCate[i] == team[m].geteventCate())
{
a3.push_back(team[m]);
}
}
if (i >= 9 && i <= 11)
{
if (teameventCate[i] == team[m].geteventCate())
{
a4.push_back(team[m]);
}
}
if (i >= 12 && i <= 14)
{
if (teameventCate[i] == team[m].geteventCate())
{
a5.push_back(team[m]);
}
}
if (i >= 15 && i <= 18)
{
if (teameventCate[i] == team[m].geteventCate())
{
a6.push_back(team[m]);
}
}
if (i >= 19 && i <= 22)
{
if (teameventCate[i] == team[m].geteventCate())
{
a7.push_back(team[m]);
}
}
if (i >= 23 && i <= 26)
{
if (teameventCate[i] == team[m].geteventCate())
{
a8.push_back(team[m]);
}
}
if (i >= 27 && i < teameventCate.size())
{
if (teameventCate[i] == team[m].geteventCate())
{
a9.push_back(team[m]);
}
}
}
}
}
3.先输出进场顺序
void Approach_sequence(vector<Team>& team)
{
for (int i = 0; i < team.size(); i++)
{
cout<<"第"<<i+1<<" 个队伍编号为:" <<team[i].getTeamID() << endl;
}
}
4.最后模拟叫号,如果输入继续,即代表前一组完成,现在即可叫下一组
void Call_system(vector<Team> team)
{
cout << "本次叫到的编号为:" << team[0].getTeamID() << endl;
team.pop_back();
for (int i = 1; i < team.size(); i++)
{
string a;
cin >> a;
if (a == "继续")
{
cout << "本次叫到的编号为:" << team[i].getTeamID() << endl;
team.pop_back();
}
else if(a!="继续")
{
cout<<"比赛还在继续,请继续等待!" << endl;
}
else if (i == team.size())
{
cout<<"比赛已经完成!" << endl;
}
}
}
校园导游系统
1.先创建一张校园地图(带权无向图)
2.代码展示:
string join(string s, vector<unsigned> list) { // 拼接向量元素为字符串
if (list.empty()) return "";
string res(to_string(list[0]));
for (auto i = list.begin() + 1; i != list.end(); ++i) {
res += s;
res += to_string(*i);
}
return res;
}
class Floyd {
private:
unsigned n; // 结点数
vector<vector<double>> mat; // 邻接矩阵
vector<vector<unsigned>> pre; // 前驱结点表
void floyd() { // Floyd算法具体实现
for (unsigned k = 0; k < n; ++k) // 依次作为中继结点
for (unsigned i = 0; i < n; ++i)
for (unsigned j = 0; j < n; ++j)
if (mat[i][j] > mat[i][k] + mat[k][j]) { // 以中继更新其他点
mat[i][j] = mat[i][k] + mat[k][j];
pre[i][j] = k;
}
}
public:
Floyd( // 构造:结点数,边集,是否无向
unsigned n,
vector<tuple<unsigned, unsigned, double>> edges,
bool undirected = true)
:n(n), mat(vector<vector<double>>(n, vector<double>(n, DBL_MAX))) {
for (unsigned i = 0; i < n; ++i) { // 生成邻接矩阵和前驱表
mat[i][i] = 0;
pre.push_back(vector<unsigned>(n, i));
}
for (auto edge : edges) {
auto i = get<0>(edge), j = get<1>(edge);
auto w = get<2>(edge);
mat[i][j] = w;
if (undirected) mat[j][i] = w;
}
floyd();
}
tuple<unsigned, string> operator()(unsigned i, unsigned j) { // 重载()获取结点i到结点j的路径
if (i == j) return { 0, to_string(i) };
if (mat[i][j] == DBL_MAX) return { DBL_MAX, "" };
vector<unsigned> p{ i, j };
unsigned k = 0;
while (k < p.size() - 1) {
auto iter = p.begin() + k;
if (pre[*iter][*(iter + 1)] == *iter) ++k;
else p.insert(iter + 1, pre[*iter][*(iter + 1)]);
}
return { mat[i][j], join("->", p) };
}
};
int identifyposition(string a)
{
if (a == "3号组团")
{
return 0;
}
if (a == "西食堂")
{
return 1;
}
if (a == "文体中心")
{
return 2;
}
if (a == "足球场")
{
return 3;
}
if (a == "文理大楼")
{
return 4;
}
if (a == "笃学楼")
{
return 5;
}
if (a == "东食堂")
{
return 6;
}
if (a == "9号组团")
{
return 7;
}
if (a == "图书馆")
{
return 8;
}
if (a == "计算机学院")
{
return 9;
}
}
void searchposition(string a,string b)
{
vector<tuple<unsigned, unsigned, double>> es{ // 起点, 终点, 权重
{0, 1, 80},
{0, 2, 150},
{1, 2, 100},
{1, 3, 90},
{1, 4, 120},
{2, 3, 50},
{2, 5, 80},
{2, 6, 160},
{3, 4, 75},
{3, 5, 70},
{4, 5, 80},
{4, 9, 80},
{5, 6, 90},
{5, 8, 80},
{5, 9, 100},
{6, 7, 50},
{6, 8, 70},
{7, 8, 80},
{8, 9, 110}, };
Floyd pathf(10, es);
int m = identifyposition(a);
int n= identifyposition(b);
cout << "地图追踪为:: " << endl;
auto tp = pathf(m,n ); // 结点i到结点j的<最短路径值, 途径结点>
cout << a<<"到" <<b<<"距离为: " << get<0>(tp) << ", 通过的地点编号为: " << get<1>(tp) << endl;
}
3.主函数输出:
int main()
{
insertinformation();
eventCate_separate(teamsall);
while (true) {
cout << "================== 赛事管理系统 ==================" << endl;
cout << "1. 添加参赛队伍" << endl;
cout << "2. 删除参赛队伍" << endl;
cout << "3. 修改参赛队伍" << endl;
cout << "4. 按参赛队编号查询参赛队伍" << endl;
cout << "5. 按参赛学校查询参赛队伍" << endl;
cout << "6. 决赛叫号功能" << endl;
cout<< "7. 地图导航功能" <<endl;
cout << "0. 退出系统" << endl;
cout << "=================================================" << endl;
cout << "请输入操作选项:";
int a;
cin >>a;
switch (a)
{
case 1:
{
string id, project, schoolname, event, participants, teacher;
cout << "请输入参赛队编号:" << endl;
cin >> id;
cout << "请输入参赛作品名称:" << endl;
cin >> project;
cout << "请输入参赛参赛学校:" << endl;
cin >> schoolname;
cout << "请输入参赛的赛事类别:" << endl;
cin >> event;
cout << "请输入参赛者:" << endl;
cin >> participants;
cout << "请输入参赛的指导老师:" << endl;
cin >> teacher;
Team a;
a.insertTeamID(id);
a.insertworkname(project);
a.insertschool(schoolname);
a.inserteventCate(event);
a.insertparticipants(participants);
a.insertteachers(teacher);
addteam(id, project, schoolname, event, participants, teacher);
addteam2(teamsall, a);
break;
}
case 2:
{
cout << "请输入你想删除的参赛队伍编号:" << endl;
string l;
cin >> l;
deleteteam(teamsall, l);
deletfile(l);
break;
}
case 3:
{
cout << "请输入你想修改的参赛队伍编号:" << endl;
string l;
cin >> l;
string id, project, schoolname, event, participants, teacher;
cout << "请输入参赛队编号:" << endl;
cin >> id;
cout << "请输入参赛作品名称:" << endl;
cin >> project;
cout << "请输入参赛参赛学校:" << endl;
cin >> schoolname;
cout << "请输入参赛的赛事类别:" << endl;
cin >> event;
cout << "请输入参赛者:" << endl;
cin >> participants;
cout << "请输入参赛的指导老师:" << endl;
cin >> teacher;
revise(l, id, project, schoolname, event, participants, teacher);
reworkteam(teamsall, l,id, project, schoolname, event, participants, teacher);
break;
}
case 4:
{
cout << "请输入你想查询的参赛队伍编号:" << endl;
string l;
cin >> l;
cout<<"*******查询结果如下:*******" << endl;
searchid(root, l);
break;
}
case 5:
{
cout << "请输入你想查询的参赛队伍的学校:" << endl;
string l;
cin >> l;
sortprint(teamsall, l);
break;
}
case 6:
{
cout << "请输入你想查询的赛区数字:" << endl;
int l;
cin >> l;
cout<<"********你想查询" <<l<<"赛区!******" << endl;
vector<Team> m = search_zone(l);
Approach_sequence(m);
Call_system(m);
break;
}
case 7:
{
Mat image = imread("C:\\Users\\Lenovo\\Desktop\\无标题.png", IMREAD_GRAYSCALE);
namedWindow("image window", WINDOW_NORMAL);
imshow("image window", image);
waitKey(0);
cout << " 0->3号组团" << endl << " 1->西食堂" << endl << " 2->文体中心" << endl << " 3->足球场" << endl << " 4->文理大楼" << endl;
cout << " 5->笃学楼" << endl << " 6->东食堂" << endl << " 7->9号组团" << endl << " 8->图书馆" << endl << " 9->计算机学院" << endl;
string e;
string f;
cout << "请输入你的起始地址:" << endl;
cin >> e;
if (identifyposition(e) < 0)
{
cout<<"输入错误!请重新输入!" << endl;
break;
}
cout << "请输入你要到达的地址:" << endl;
cin >> f;
if (identifyposition(f) < 0)
{
cout << "输入错误!请重新输入!" << endl;
break;
}
searchposition(e, f);
break;
}
case 0:
cout << "感谢使用赛事管理系统!再见!" << endl;
return 0;
default:
cout << "无效的操作选项!请重新输入。" << endl;
break;
}
cout << endl;
}
std::system("PAUSE");
return 0;
}
四、实验结果
附源码如下:
#include<iostream>
#include<fstream>
#include <string>
#include<vector>
#include <sstream>
#include <cstdlib>
#include <algorithm>
#include <tuple>
#include <chrono>
#include <thread>
using namespace cv;
using namespace std;
using namespace chrono;
class Team {
private:
//基本信息
string TeamID; //参赛队编号
string workname; //参赛作品名称
string school; //参赛学校
string eventCate; //赛事类别 赛事类别共11项
string participants; //参赛者
string teachers; //指导老师
public:
//构造Team
Team() = default;
Team(string id, string Workname, string schoolname, string eventcatename, string Participant, string Teacher)
{
TeamID = id;
workname = Workname;
school = schoolname;
eventCate = eventcatename;
participants = Participant;
teachers = Teacher;
}
//输出参赛队编号
string getTeamID() {
return TeamID;
}
//输出作品名称
string getworkname() {
return workname;
}
string getschool() {
return school;
}
string geteventCate() {
return eventCate;
}
string getparticipants() {
return participants;
}
string getteachers() {
return teachers;
}
void insertTeamID(string id)
{
TeamID = id;
}
void insertworkname(string Workname)
{
workname = Workname;
}
void insertschool(string schoolname)
{
school = schoolname;
}
void inserteventCate(string eventcatename)
{
eventCate = eventcatename;
}
void insertparticipants(string Participant)
{
participants = Participant;
}
void insertteachers(string Teacher)
{
teachers = Teacher;
}
};
//二叉排序树
struct TreeNode {
Team data;
TreeNode* left;
TreeNode* right;
};
//添加信息
vector<Team> teamsall;//储存从txt文档中提取到的信息
TreeNode* root;//创建一个二叉排序树
vector<long long> teamID;//变成long long形的id顺序(用于储存参赛队伍的编号)
//九个决赛区
vector<Team> a1;
vector<Team> a2;
vector<Team> a3;
vector<Team> a4;
vector<Team> a5;
vector<Team> a6;
vector<Team> a7;
vector<Team> a8;
vector<Team> a9;
//增加参赛队伍
void addteam(string id, string project,string schoolname,string event,string participants,string teacher)
{
ofstream file("E:\\team.txt", ios::app);
file << id <<" #" <<project<<" #" << " #" <<schoolname<< " #" <<event<< " #"<<participants<< " #" <<teacher<<endl;
file.close();
}
void addteam2(vector<Team>& team, Team a)
{
team.push_back(a);
}
//删除参赛队伍
void deleteteam(vector<Team>& team, string id)
{
for (int i = 0; i < team.size(); i++)
{
if (team[i].getTeamID() == id)
{
team.erase(team.begin() + i);
cout << "删除成功!" << endl;
return;
}
}
cout << "里面没有这个参赛队伍" << endl;
}
void deletfile(string id)
{
fstream is("D:\\team.txt", ios::in);
vector<Team> data; // 存储文件数据
Team a;
string buf;
while (std::getline(is, buf))
{
buf.erase(remove(buf.begin(), buf.end(), '\t'), buf.end());
string bufs;
vector<string> items;
stringstream ss(buf);
while (getline(ss, bufs, '#'))
{
items.push_back(bufs);
}
if (items.size() == 6)
{
a.insertTeamID(items[0]);
a.insertworkname(items[1]);
a.insertschool(items[2]);
a.inserteventCate(items[3]);
a.insertparticipants(items[4]);
a.insertteachers(items[5]);
data.push_back(a);
}
}
is.close();
for (int i = 0; i < data.size(); i++)
{
if (data[i].getTeamID() == id)
{
data.erase(data.begin() + i);
}
}
ofstream file("D:\\team.txt");
for (int i = 0; i < data.size(); i++)
{
file << data[i].getTeamID() << "#" << data[i].getworkname() << "#" << data[i].getschool() << "#" << data[i].geteventCate() << "#" << data[i].getparticipants() << "#" << data[i].getteachers() << endl;
}
file.close();
}
//修改参赛队伍的信息
void reworkteam(vector<Team>& team, string id, string id1, string project, string schoolname, string event, string participants, string teacher)
{
for (int i = 0; i < team.size(); i++)
{
if(team[i].getTeamID()==id)
{
team[i].insertTeamID(id1);
team[i].insertschool(schoolname);
team[i].insertworkname(project);
team[i].inserteventCate(event);
team[i].insertparticipants(participants);
team[i].insertteachers(teacher);
cout<<"修改成功!" << endl;
}
}
}
void revise(string id,string id1, string project, string schoolname, string event, string participants, string teacher)
{
fstream is("D:\\team.txt", ios::in);
vector<Team> data; // 存储文件数据
Team a;
string buf;
while (std::getline(is, buf))
{
buf.erase(remove(buf.begin(), buf.end(), '\t'), buf.end());
string bufs;
vector<string> items;
stringstream ss(buf);
while (getline(ss, bufs, '#'))
{
items.push_back(bufs);
}
if (items.size() == 6)
{
a.insertTeamID(items[0]);
a.insertworkname(items[1]);
a.insertschool(items[2]);
a.inserteventCate(items[3]);
a.insertparticipants(items[4]);
a.insertteachers(items[5]);
data.push_back(a);
}
}
is.close();
for (int i = 0; i < data.size(); i++)
{
if (data[i].getTeamID() == id)
{
data.erase(data.begin() + i);
}
}
ofstream file("D:\\team.txt");
for (int i = 0; i < data.size(); i++)
{
file << data[i].getTeamID() << "#" << data[i].getworkname() << "#" << data[i].getschool() << "#" << data[i].geteventCate() << "#" << data[i].getparticipants() << data[i].getteachers() << endl;
}
file.close();
ofstream fie("D:\\team.txt", ios::app);
fie << id1 << " #" << project << " #" << " #" << schoolname << " #" << event << " #" << participants << " #" << teacher << endl;
fie.close();
}
void insertTreeNode(TreeNode*& tree, Team& team) {
if (tree == nullptr) {
tree = new TreeNode;
tree->data = team;
tree->left = NULL;
tree->right = NULL;
return;
}
long long a= std::atoi(team.getTeamID().c_str());
long long b= std::atoi(tree->data.getTeamID().c_str());
if (a < b) {
insertTreeNode(tree->left, team);
}
else {
insertTreeNode(tree->right, team);
}
}
//导入team.txt文件,并把编号录入二叉排序树当中(第二题)
void insertinformation()
{
ifstream ifs;
string buf;
Team a;
teamsall.clear();
root = nullptr;
ifs.open("D:\\team.txt", ios::in);
if (!ifs.is_open())
{
cout << "文件打开失败" << endl;
}
else
{
while (std::getline(ifs, buf))
{
buf.erase(remove(buf.begin(), buf.end(), '\t'), buf.end());
string bufs;
vector<string> items;
stringstream ss(buf);
while (getline(ss, bufs, '#'))
{
items.push_back(bufs);
}
if (items.size() == 6)
{
a.insertTeamID(items[0]);
a.insertworkname(items[1]);
a.insertschool(items[2]);
a.inserteventCate(items[3]);
a.insertparticipants(items[4]);
a.insertteachers(items[5]);
teamsall.push_back(a);
insertTreeNode(root, a);
}
}
}
ifs.close();
}
//求平均查找长度
int ASL(TreeNode* node, string key, int depth) {
if (!node) return -1;
long long c = std::atoi(key.c_str());
long long d = std::atoi(node->data.getTeamID().c_str());
if (c == d) return depth;
if (c < d)
return ASL(node->left, key, ++depth);
else
return ASL(node->right, key, ++depth);
}
//根据提示输入参赛学校编号
void searchid(TreeNode* node, string id)
{
long long c= std::atoi(id.c_str());
long long d= std::atoi(node->data.getTeamID().c_str());
if (node== NULL)
{
return;
}
if (d == c)
{
int a = ASL(root, id, 0);
cout <<"此时查找成功后的平均长度为:" << a << endl;
cout<<"参赛队编号:" << node->data.getTeamID() << endl;
cout <<"参赛作品名称:" << node->data.getworkname() << endl;
cout <<"参赛学校为:" << node->data.getschool() << endl;
cout <<"赛事类别为:" << node->data.geteventCate() << endl;
cout<<"参赛者名字叫:" << node->data.getparticipants() << endl;
cout <<"指导老师叫:" << node->data.getteachers() << endl;
}
else if (c < d)
{
searchid(node->left,id);
}
else if (c > d)
{
searchid(node->right, id);
}
}
//插入排序(第三题)
void insertionSort(vector<long long>& arr) {
int n = arr.size();
for (int i = 1; i < n; i++) {
int key = arr[i];
int j = i - 1;
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key;
}
}
//插入排序的输出
void sortprint(vector<Team> team, string schoolname)
{
vector<Team> team1;
for (int i = 0; i < team.size(); i++)
{
if (team[i].getschool() == schoolname)
{
team1.push_back(team[i]);
}
}
for (int m = 0; m < team1.size(); m++)
{
long long a = std::atoi(team1[m].getTeamID().c_str());
teamID.push_back(a);
}
insertionSort(teamID);
for (int k = 0; k < teamID.size(); k++)
{
for (int m= 0; m < team1.size(); m++)
{
long long a = std::atoi(team1[m].getTeamID().c_str());
if (a == teamID[k])
{
cout << "参赛队编号:" << team1[m].getTeamID() << endl;
cout << "参赛作品名称:" << team1[m].getworkname() << endl;
cout << "参赛学校为:" << team1[m].getschool() << endl;
cout << "赛事类别为:" << team1[m].geteventCate() << endl;
cout << "参赛者名字叫:" << team1[m].getparticipants() << endl;
cout << "指导老师叫:" << team1[m].getteachers() << endl;
}
}
}
}
//叫号系统
//赛区分类
void eventCate_separate(vector<Team> team)
{
vector<string> teameventCate;
for (int i = 0; i < team.size(); i++)
{
if (std::find(teameventCate.begin(), teameventCate.end(), team[i].geteventCate()) == teameventCate.end())
{
teameventCate.push_back(team[i].geteventCate());
}
}
for (int i = 0; i < teameventCate.size(); i++)
{
for (int m = 0; m < team.size(); m++)
{
if (i < 3)
{
if (teameventCate[i] ==team[m].geteventCate())
{
a1.push_back(team[m]);
}
}
if (i>=3&&i<=5)
{
if (teameventCate[i] == team[m].geteventCate())
{
a2.push_back(team[m]);
}
}
if (i >= 6 && i <= 8)
{
if (teameventCate[i] == team[m].geteventCate())
{
a3.push_back(team[m]);
}
}
if (i >= 9 && i <= 11)
{
if (teameventCate[i] == team[m].geteventCate())
{
a4.push_back(team[m]);
}
}
if (i >= 12 && i <= 14)
{
if (teameventCate[i] == team[m].geteventCate())
{
a5.push_back(team[m]);
}
}
if (i >= 15 && i <= 18)
{
if (teameventCate[i] == team[m].geteventCate())
{
a6.push_back(team[m]);
}
}
if (i >= 19 && i <= 22)
{
if (teameventCate[i] == team[m].geteventCate())
{
a7.push_back(team[m]);
}
}
if (i >= 23 && i <= 26)
{
if (teameventCate[i] == team[m].geteventCate())
{
a8.push_back(team[m]);
}
}
if (i >= 27 && i < teameventCate.size())
{
if (teameventCate[i] == team[m].geteventCate())
{
a9.push_back(team[m]);
}
}
}
}
}
//获得你想要的赛区
vector<Team> search_zone(int i)
{
if (i == 1)
{
return a1;
}
if (i == 2)
{
return a2;
}
if (i == 3)
{
return a3;
}
if (i == 4)
{
return a4;
}
if (i == 5)
{
return a5;
}
if (i == 6)
{
return a6;
}
if (i == 7)
{
return a7;
}
if (i == 8)
{
return a8;
}
if (i == 9)
{
return a9;
}
}
//进场顺序
void Approach_sequence(vector<Team>& team)
{
for (int i = 0; i < team.size(); i++)
{
cout<<"第"<<i+1<<" 个队伍编号为:" <<team[i].getTeamID() << endl;
}
}
//模拟叫号
void Call_system(vector<Team> team)
{
cout<<"********叫号开始!**********" << endl;
int i = 0;
while (i < team.size())
{
cout << "第" << i+1 << "次叫到的编号为:" << team[i].getTeamID() << endl;
this_thread::sleep_for(seconds(1));
i++;
}
}
//导航系统(第五题)
string join(string s, vector<unsigned> list) { // 拼接向量元素为字符串
if (list.empty()) return "";
string res(to_string(list[0]));
for (auto i = list.begin() + 1; i != list.end(); ++i) {
res += s;
res += to_string(*i);
}
return res;
}
class Floyd {
private:
unsigned n; // 结点数
vector<vector<double>> mat; // 邻接矩阵
vector<vector<unsigned>> pre; // 前驱结点表
void floyd() { // Floyd算法具体实现
for (unsigned k = 0; k < n; ++k) // 依次作为中继结点
for (unsigned i = 0; i < n; ++i)
for (unsigned j = 0; j < n; ++j)
if (mat[i][j] > mat[i][k] + mat[k][j]) { // 以中继更新其他点
mat[i][j] = mat[i][k] + mat[k][j];
pre[i][j] = k;
}
}
public:
Floyd( // 构造:结点数,边集,是否无向
unsigned n,
vector<tuple<unsigned, unsigned, double>> edges,
bool undirected = true)
:n(n), mat(vector<vector<double>>(n, vector<double>(n, DBL_MAX))) {
for (unsigned i = 0; i < n; ++i) { // 生成邻接矩阵和前驱表
mat[i][i] = 0;
pre.push_back(vector<unsigned>(n, i));
}
for (auto edge : edges) {
auto i = get<0>(edge), j = get<1>(edge);
auto w = get<2>(edge);
mat[i][j] = w;
if (undirected) mat[j][i] = w;
}
floyd();
}
tuple<unsigned, string> operator()(unsigned i, unsigned j) { // 重载()获取结点i到结点j的路径
if (i == j) return { 0, to_string(i) };
if (mat[i][j] == DBL_MAX) return { DBL_MAX, "" };
vector<unsigned> p{ i, j };
unsigned k = 0;
while (k < p.size() - 1) {
auto iter = p.begin() + k;
if (pre[*iter][*(iter + 1)] == *iter) ++k;
else p.insert(iter + 1, pre[*iter][*(iter + 1)]);
}
return { mat[i][j], join("->", p) };
}
};
int identifyposition(string a)
{
if (a == "3号组团")
{
return 0;
}
if (a == "西食堂")
{
return 1;
}
if (a == "文体中心")
{
return 2;
}
if (a == "足球场")
{
return 3;
}
if (a == "文理大楼")
{
return 4;
}
if (a == "笃学楼")
{
return 5;
}
if (a == "东食堂")
{
return 6;
}
if (a == "9号组团")
{
return 7;
}
if (a == "图书馆")
{
return 8;
}
if (a == "计算机学院")
{
return 9;
}
else
{
return -1;
}
}
void searchposition(string a,string b)//用于输入搜索并且打印地址
{
vector<tuple<unsigned, unsigned, double>> es{ // 起点, 终点, 权重
{0, 1, 80},
{0, 2, 150},
{1, 2, 100},
{1, 3, 90},
{1, 4, 120},
{2, 3, 50},
{2, 5, 80},
{2, 6, 160},
{3, 4, 75},
{3, 5, 70},
{4, 5, 80},
{4, 9, 80},
{5, 6, 90},
{5, 8, 80},
{5, 9, 100},
{6, 7, 50},
{6, 8, 70},
{7, 8, 80},
{8, 9, 110}, };
Floyd pathf(10, es);
int m = identifyposition(a);
int n= identifyposition(b);
cout << "地图追踪为:: " << endl;
auto tp = pathf(m,n ); // 结点i到结点j的<最短路径值, 途径结点>
cout << a<<"到" <<b<<"距离为: " << get<0>(tp) << ", 通过的地点编号为: " << get<1>(tp) << endl;
}
int main()
{
insertinformation();
eventCate_separate(teamsall);
while (true) {
cout << "================== 赛事管理系统 ==================" << endl;
cout << "1. 添加参赛队伍" << endl;
cout << "2. 删除参赛队伍" << endl;
cout << "3. 修改参赛队伍" << endl;
cout << "4. 按参赛队编号查询参赛队伍" << endl;
cout << "5. 按参赛学校查询参赛队伍" << endl;
cout << "6. 决赛叫号功能" << endl;
cout<< "7. 地图导航功能" <<endl;
cout << "0. 退出系统" << endl;
cout << "=================================================" << endl;
cout << "请输入操作选项:";
int a;
cin >>a;
switch (a)
{
case 1:
{
string id, project, schoolname, event, participants, teacher;
cout << "请输入参赛队编号:" << endl;
cin >> id;
cout << "请输入参赛作品名称:" << endl;
cin >> project;
cout << "请输入参赛参赛学校:" << endl;
cin >> schoolname;
cout << "请输入参赛的赛事类别:" << endl;
cin >> event;
cout << "请输入参赛者:" << endl;
cin >> participants;
cout << "请输入参赛的指导老师:" << endl;
cin >> teacher;
Team a;
a.insertTeamID(id);
a.insertworkname(project);
a.insertschool(schoolname);
a.inserteventCate(event);
a.insertparticipants(participants);
a.insertteachers(teacher);
addteam(id, project, schoolname, event, participants, teacher);
addteam2(teamsall, a);
break;
}
case 2:
{
cout << "请输入你想删除的参赛队伍编号:" << endl;
string l;
cin >> l;
deleteteam(teamsall, l);
deletfile(l);
break;
}
case 3:
{
cout << "请输入你想修改的参赛队伍编号:" << endl;
string l;
cin >> l;
string id, project, schoolname, event, participants, teacher;
cout << "请输入参赛队编号:" << endl;
cin >> id;
cout << "请输入参赛作品名称:" << endl;
cin >> project;
cout << "请输入参赛参赛学校:" << endl;
cin >> schoolname;
cout << "请输入参赛的赛事类别:" << endl;
cin >> event;
cout << "请输入参赛者:" << endl;
cin >> participants;
cout << "请输入参赛的指导老师:" << endl;
cin >> teacher;
revise(l, id, project, schoolname, event, participants, teacher);
reworkteam(teamsall, l,id, project, schoolname, event, participants, teacher);
break;
}
case 4:
{
cout << "请输入你想查询的参赛队伍编号:" << endl;
string l;
cin >> l;
cout<<"*******查询结果如下:*******" << endl;
searchid(root, l);
break;
}
case 5:
{
cout << "请输入你想查询的参赛队伍的学校:" << endl;
string l;
cin >> l;
sortprint(teamsall, l);
break;
}
case 6:
{
cout << "请输入你想查询的赛区数字:" << endl;
int l;
cin >> l;
cout<<"********你想查询" <<l<<"赛区!******" << endl;
vector<Team> m = search_zone(l);
Approach_sequence(m);
Call_system(m);
break;
}
case 7:
{
Mat image = imread("C:\\Users\\Lenovo\\Desktop\\无标题.png", IMREAD_GRAYSCALE);
namedWindow("image window", WINDOW_NORMAL);
imshow("image window", image);
waitKey(0);
cout << " 0->3号组团" << endl << " 1->西食堂" << endl << " 2->文体中心" << endl << " 3->足球场" << endl << " 4->文理大楼" << endl;
cout << " 5->笃学楼" << endl << " 6->东食堂" << endl << " 7->9号组团" << endl << " 8->图书馆" << endl << " 9->计算机学院" << endl;
string e;
string f;
cout << "请输入你的起始地址:" << endl;
cin >> e;
if (identifyposition(e) < 0)
{
cout<<"输入错误!请重新输入!" << endl;
break;
}
cout << "请输入你要到达的地址:" << endl;
cin >> f;
if (identifyposition(f) < 0)
{
cout << "输入错误!请重新输入!" << endl;
break;
}
searchposition(e, f);
break;
}
case 0:
cout << "感谢使用赛事管理系统!再见!" << endl;
return 0;
default:
cout << "无效的操作选项!请重新输入。" << endl;
break;
}
cout << endl;
}
std::system("PAUSE");
return 0;
}