课设预习日志

一、任务分析

本次课程设计要求协助中国大学生计算机设计大赛江苏省组委会,设计一款赛事管理系统,实现赛务相关的数据管理及信息服务。该系统能够为省级赛事管理解决以下问题:

  1. 能够管理各参赛队的基本信息(包含参赛队编号,参赛作品名称,参赛学校,赛事类别,参赛者,指导老师),赛事类别共11项;包括增加、删除、修改参赛队伍的信息。
  2. 从team.txt中读取参赛队伍的基本信息,实现基于二叉排序树的查找。根据提示输入参赛队编号,若查找成功,输出该赛事类别对应的基本信息,同时,输出查找成功时的平均查找长度ASL;否则,输出“查找失败!”。
  3. 能够提供按参赛学校查询参赛团队(或根据赛事类别查询参赛团队),即,根据提示输入参赛学校名称(赛事类别),若查找成功,输出该学校参赛的(该赛事类别的)所有团队的基本信息,输出的参赛团队按赛事类别有序输出。
  4. 为省赛现场设计一个决赛叫号系统。所有参赛队按赛事组织文件中的赛事类别分到9个决赛室,决赛室按顺序叫号,被叫号参赛队进场,比赛结束后,下一参赛队才能进赛场。请模拟决赛叫号系统,演示省赛现场各决赛室的参赛队进场情况。
  5. 赛事系统为参赛者提供赛地的校园导游程序,为参赛者提供各种路径导航的查询服务。以我校长山校区提供比赛场地为例,(请为参赛者提供不少于10个目标地的导航)。可为参赛者提供校园地图中任意目标地(建筑物)相关信息的查询;提供任意两个目标地(建筑物)的导航查询,即查询任意两个目的地(建筑物)之间的一条最短路径。

二、模块划分

根据任务分析,我们可以将系统划分为以下模块:

  1. 参赛队伍信息管理模块:包括增加、删除、修改参赛队伍的信息,以及从team.txt中读取参赛队伍信息的功能。
  2. 参赛队伍信息查询模块:包括基于二叉排序树的参赛队伍信息查找,以及按参赛学校查询参赛团队(或根据赛事类别查询参赛团队)的功能。
  3. 决赛叫号系统模块:模拟决赛叫号系统,演示省赛现场各决赛室的参赛队进场情况。
  4. 赛地导航查询模块:提供校园地图中任意目标地(建筑物)相关信息的查询,以及提供任意两个目标地(建筑物)的导航查询的功能。

三、数据结构设计

  1. 参赛队伍信息的数据结构设计:
typedef struct {
    char team_id[10]; // 参赛队编号
    char team_name[50]; // 参赛作品名称
    char team_school[50]; // 参赛学校
    int team_category; // 赛事类别,共11项
    char team_members[100]; // 参赛者
    char team_teacher[50]; // 指导老师
} Team;
  1. 根据参赛队编号查找参赛队伍信息的二叉排序树的数据结构设计:
typedef struct node {
    Team team; // 参赛队伍信息
    struct node* lchild; // 左子树
    struct node* rchild; // 右子树
} Node;

四、算法设计

  1. 参赛队伍信息的增加、删除、修改操作的算法设计:
void add_team(Team team); // 增加参赛队伍信息
void delete_team(char* team_id); // 删除参赛队伍信息
void modify_team(char* team_id, Team new_team); // 修改参赛队伍信息
  1. 从team.txt中读取参赛队伍信息的算法设计:
void read_teams(); // 从team.txt中读取参赛队伍信息
  1. 根据参赛队编号查找参赛队伍信息的二叉排序树的算法设计:
Node* find_team(Node* root, char* team_id); // 查找参赛队伍信息
double get_asl(Node* root, char* team_id, int level); // 计算平均查找长度ASL
  1. 按参赛学校查询参赛团队(或根据赛事类别查询参赛团队)的算法设计:
void search_by_school(char* school); // 按参赛学校查询参赛团队
void search_by_category(int category); // 根据赛事类别查询参赛团队
  1. 决赛叫号系统的算法设计:
void call_teams(); // 模拟决赛叫号系统
  1. 赛地导航查询的算法设计:
void show_map(); // 展示校园地图
void search_location(); // 根据建筑物名称查询相关信息
void search_path(); // 查询两个建筑物之间的最短路径

五、界面设计

根据模块划分,我们可以设计出以下菜单:

  1. 参赛队伍信息管理菜单:
1.1 增加参赛队伍信息
1.2 删除参赛队伍信息
1.3 修改参赛队伍信息
  1. 参赛队伍信息查询菜单:
2.1 根据参赛队编号查找参赛队伍信息
2.2 按参赛学校查询参赛团队
2.3 根据赛事类别查询参赛团队
  1. 决赛叫号系统菜单:
3.1 模拟决赛叫号系统
  1. 赛地导航查询菜单:
4.1 展示校园地图
4.2 根据建筑物名称查询相关信息
4.3 查询两个建筑物之间的最短路径

程旭如下

#include<thread>
#include<chrono>
#include<queue>
#include<iostream>
#include <fstream>
#include <string>
#include<vector>
#include<iomanip>
#include<sstream>
using namespace std;
const int INF = 0x3f3f3f3f; // 表示无穷大
const int MAXN = 100005; // 表示最大顶点数
//图
struct Edge {
    int to, w;//to 终点,w距离
    Edge(int to, int w) : to(to), w(w) {}
};

int n, m; // n表示顶点数,m表示边数
vector<Edge> G[MAXN]; // vector存储图
int dist[MAXN]; // 存储起点到各顶点的距离
bool vis[MAXN]; // 存储某个点是否已经加入了最短路径树

void dijkstra(int s) {
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
    fill(dist + 1, dist + n + 1, INF);
    fill(vis + 1, vis + n + 1, false);
    dist[s] = 0;
    pq.push(make_pair(0, s));
    while (!pq.empty()) {
        pair<int, int> p = pq.top(); pq.pop();
        int v = p.second;
        if (vis[v]) continue;
        vis[v] = true;
        for (Edge e : G[v]) {
            if (dist[e.to] > dist[v] + e.w) {//如果e.to到起点的距离大于e.to的前驱节点+
                dist[e.to] = dist[v] + e.w;
                pq.push(make_pair(dist[e.to], e.to));//第一个值距离,第二个顶点
            }
        }
    }
}
struct Team {
    string ID; // 赛队编号
    string projectName; // 参赛作品名称
    string school; // 参赛学校
    string category; // 赛事类别
    string members; // 参赛者
    string teacher; // 指导老师
};
// 全局变量,存储所有的赛队信息
vector<Team> teams;
// 增加新的赛队信息
void addTeam() {
    Team team;
    cout << "请输入赛队编号:";
    cin >> team.ID;
    cout << "请输入参赛作品名称:";
    cin >> team.projectName;
    cout << "请输入参赛学校:";
    cin >> team.school;
    cout << "请输入赛事类别:";
    cin >> team.category;
    cout << "请输入参赛者:";
    cin >> team.members;
    cout << "请输入指导老师:";
    cin >> team.teacher;
    teams.push_back(team);
    cout << "赛队信息添加成功!" << endl;
}
// 修改指定赛队信息
void modifyTeam() {
    string ID;
    cout << "请输入需要修改信息的赛队编号:";
    cin >> ID;
    for (auto& team : teams) {
        if (team.ID == ID) {
            cout << "请输入新的参赛作品名称:";
            cin >> team.projectName;
            cout << "请输入新的参赛学校:";
            cin >> team.school;
            cout << "请输入新的赛事类别:";
            cin >> team.category;
            cout << "请输入新的参赛者:";
            cin >> team.members;
            cout << "请输入新的指导老师:";
            cin >> team.teacher;
            cout << "赛队信息修改成功!" << endl;
            return;
        }
    }
    cout << "未找到指定赛队信息!" << endl;
}// 删除指定赛队信息
void deleteTeam() {
    string ID;
    cout << "请输入需要删除信息的赛队编号:";
    cin >> ID;
    for (auto it = teams.begin(); it != teams.end(); it++) {
        if (it->ID == ID) {
            teams.erase(it);
            cout << "赛队信息删除成功!" << endl;
            return;
        }
    }
    cout << "未找到指定赛队信息!" << endl;
}
struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

//基于二叉树排序查找
void insert(TreeNode*& root, int val) {
    if (!root) {
        root = new TreeNode(val);
        return;
    }
    if (val < root->val) {
        insert(root->left, val);
    }
    else if (val > root->val) {
        insert(root->right, val);
    }
}

int search(TreeNode* root, int val, int depth) {
    if (!root) {
        return -1;
    }
    if (val == root->val) {
        return depth;
    }
    else if (val < root->val) {
        return search(root->left, val, depth + 1) + 1;
    }
    else {
        return search(root->right, val, depth + 1) + 1;
    }
}

//归并排序查找
void merge(int arr[], int low, int mid, int high) {
    int leftSize = mid - low + 1;
    int rightSize = high - mid;
    int* leftArr = new int[leftSize];
    int* rightArr = new int[rightSize];

    for (int i = 0; i < leftSize; ++i) {
        leftArr[i] = arr[low + i];
    }

    for (int j = 0; j < rightSize; ++j) {
        rightArr[j] = arr[mid + 1 + j];
    }

    int i = 0, j = 0, k = low;
    while (i < leftSize && j < rightSize) {
        if (leftArr[i] <= rightArr[j]) {
            arr[k++] = leftArr[i++];
        }
        else {
            arr[k++] = rightArr[j++];
        }
    }

    while (i < leftSize) {
        arr[k++] = leftArr[i++];
    }

    while (j < rightSize) {
        arr[k++] = rightArr[j++];
    }

    delete[] leftArr;
    delete[] rightArr;
}

// 归并排序函数
void mergeSort(int arr[], int low, int high) {
    if (low < high) {
        int mid = (low + high) / 2;
        mergeSort(arr, low, mid);
        mergeSort(arr, mid + 1, high);
        merge(arr, low, mid, high);
    }
}

// 查找函数(二分法)
int binarySearch(int arr[], int low, int high, int target) {
    if (low > high) {
        return -1;
    }

    int mid = (low + high) / 2;
    if (arr[mid] == target) {
        return mid;
    }
    else if (arr[mid] < target) {
        return binarySearch(arr, mid + 1, high, target);
    }
    else {
        return binarySearch(arr, low, mid - 1, target);
    }
}


int main()
{
    //读取文件,并将文件中的内容存放到数组当中
    int count = 0;
    Team team[399];
    ifstream fin("C:\\Users\\李一奎\\Documents\\Visual Studio 2010\\Projects\\课设\\team.txt"); // 打开存储数据的文件
    if (!fin) {
        cout << "文件打开失败!" << endl;
        return 0;
    }
    string line;
    while (getline(fin, line)) { // 逐行读取文件内容
        int pos = 0; // 记录#出现的位置
        int index = 0; // 记录当前读取到的字段
        int s = 0;
        while (pos != string::npos) { // 在当前行中查找#
            pos = line.find('#', index);
            string field = line.substr(index, pos - index); // 提取#之前的内容
            field.erase(remove(field.begin(), field.end(), '\t'), field.end());
            switch (s) { // 根据#出现的位置将提取的内容储存到相应的数组中
            case 0:
               team[count].ID = field;
                s++;
                break;
            case 1:
                team[count].projectName = field;
                s++;
                break;
            case 2:
                team[count].school = field;
                s++;
                break;
            case 3:
                team[count].category = field;
                s++;
                break;
            case 4:
                team[count].members = field;
                s++;
                break;
            case 5:
                team[count].teacher = field;
                s++;
                break;
            }
            index = pos + 1;
        }
        count++; // 计数器加1
    }
    fin.close(); // 关闭文件

    for (int i = 1; i < count; i++) {
        Team t;
        t.ID = team[i].ID;
        t.projectName = team[i].projectName;
        t.school = team[i].school;
        t.category = team[i].category;
        t.members = team[i].members;
        t.teacher = team[i].teacher;
        teams.push_back(t);
    }
    int a;
    do
    {
        cout << "这是一个赛事管理系统,输入下列编号,即可实现各种功能\n";
        cout << "1.管理赛事信息\n\n2.查找赛事信息\n\n3.按学校查询参赛团队\n\n4.决赛叫号系统\n\n5.导航功能\n\n0.退出\n";
        cin >> a;
        switch (a)
        {
        case 1: {
            int choice;
            while (true) {
                cout << "请选择操作:1.增加赛队信息  2.修改指定赛队信息 3.删除指定赛队信息 4.退出" << endl;
                cin >> choice;
                switch (choice) {
                case 1:
                    addTeam();
                    break;
                case 2:
                    modifyTeam();
                    break;
                case 3:
                    deleteTeam();
                    break;
                case 4:
                    cout << "程序已退出!" << endl;
                    return 0;
                default:
                    cout << "输入有误,请重新输入!" << endl;
                    break;
                }
            }
        }
              break;
        case 2: {
            int n = 399;
            // 建立二叉排序树
            int number[500]{};
            TreeNode* root = NULL;
            for (int i = 1; i < n; i++) {
                number[i] = stoi(team[i].ID);
                insert(root, number[i]);
            }
            int val, ch;
            cout << "请输入要查找的参赛队编号:";
            cin >> val;
            for (int i = 0; i < n; i++) {
                if (number[i] == val)
                    ch = i;
            }
            int depth = 0;
            for (int i = 1; i < n; i++) {
                number[i] = stoi(team[i].ID);
                depth = depth + search(root, number[i], 1);         
            }
            if (depth == -1) {
                cout << "查找失败!" << endl;
            }
            else {//参赛队编号,参赛作品名称,参赛学校,赛事类别,参赛者,指导老师
                cout << "参赛队编号为:" << val << endl;
                cout << "参赛作品名称:" << team[ch].projectName << endl;
                cout << "参赛学校:" << team[ch].school << endl;
                cout << "赛事类别:" << team[ch].category << endl;
                cout << "参赛者:" << team[ch].members << endl;
                cout << "指导老师:" << team[ch].teacher << endl;
                cout << "平均查找长度ASL为:" << (double)depth / (n-1) << endl;
            }
            break;
        }
        case 3: {
            string school_name;
            cout << "请输入学校名称:";
            cin >> school_name;
            int n = 399;
            int count = 0;
            for (int i = 0; i < n - 1; i++) {
                if (teams[i].school.compare(school_name) == 0) {
                    count++;
                }
            }
            if (count == 0) {
                cout << "未找到该学校的参赛团队!" << endl;
            }
            else {
                int* found_teams = new int[count];
                int index = 0;
                for (int i = 0; i < n - 1; i++) {
                    if (teams[i].school.compare(school_name) == 0) {
                        found_teams[index] = stoi(teams[i].ID);
                        index++;
                    }
                }
                mergeSort(found_teams, 0, count - 1);
                cout << "参赛队编号\t" << "参赛作品名称\t" << "参赛学校\t" << "赛事类别\t" << "参赛者\t" << "指导老师\t\n";
                for (int i = 0; i < count; i++) {
                    for (int j = 0; j < 398; j++) {
                        if (found_teams[i] == stoi(teams[j].ID)) {
                            cout << teams[j].ID << "\t";
                            cout << teams[j].projectName << "\t";
                            cout << teams[j].school << "\t";
                            cout << teams[j].category << "\t";
                            cout << teams[j].members << "\t";
                            cout << teams[j].teacher << endl;
                        }
                    }
                }
                delete[] found_teams;
            }
        }
              break;
        case 4: {
            int arr[398] = { 0 };
            for (int i = 0; i < 398; i++) {
                arr[i] = stoi(teams[i].ID);
            }; // 假设已有400组编号被存储在arr数组中
            queue<int> q; // 定义一个循环队列,最大容量为9
            int index = 0; // 当前处理的队伍编号在arr数组中的下标
            while (index < 398 || !q.empty()) { // 比较队伍编号数组的长度和循环队列是否都为空
                if (q.size() == 9) { // 计时器时间到达队伍进入时间而且队列中有9个队伍
                    cout << "比赛开始:"<< endl;// 输出提示信息

                    for (int i = 0; i < 9; ++i) { // 取出队首的9个队伍进行比赛
                        cout << q.front() << "\n";
                        q.pop();

                    }
                    cout << endl; // 输出换行符

                    this_thread::sleep_for(chrono::milliseconds(500));
                }

                if (index < 398) { // 队伍编号数组还有剩余队伍
                    q.push(arr[index++]); // 将当前处理的队伍编号添加到队列
                }
               this_thread::yield(); // 等待其他程序运行
            }

        }
              break;
        case 5: {
            // 读入n,m和边集E
            n = 10;
            m = 14;
            G[1].push_back(Edge(2, 100));
            G[1].push_back(Edge(4, 200));
            G[2].push_back(Edge(1, 100));
            G[2].push_back(Edge(3, 80));
            G[2].push_back(Edge(4, 150));
            G[3].push_back(Edge(2, 80));
            G[3].push_back(Edge(5, 120));
            G[3].push_back(Edge(6, 110));
            G[4].push_back(Edge(1, 200));
            G[4].push_back(Edge(2, 150));
            G[4].push_back(Edge(5, 50));
            G[5].push_back(Edge(3, 120));
            G[5].push_back(Edge(4, 50));
            G[5].push_back(Edge(8, 150));
            G[5].push_back(Edge(9, 230));
            G[6].push_back(Edge(3, 110));
            G[6].push_back(Edge(7, 80));
            G[6].push_back(Edge(8, 60));
            G[7].push_back(Edge(6, 80));
            G[7].push_back(Edge(10, 100));
            G[8].push_back(Edge(5, 150));
            G[8].push_back(Edge(9, 90));
            G[8].push_back(Edge(6, 60));
            G[8].push_back(Edge(10, 70));
            G[9].push_back(Edge(5, 230));
            G[9].push_back(Edge(8, 90));
            G[9].push_back(Edge(10, 50));
            G[10].push_back(Edge(7, 100));
            G[10].push_back(Edge(8, 70));
            G[10].push_back(Edge(9, 50));

            // 输入起点和终点
            int start, end;
            cout << "请输入起点和终点:";
            cin >> start >> end;

            // 运行Dijkstra算法
            dijkstra(start);

            // 输出结果
            cout << "最短路径的途径编号为:";
            vector<int> path;
            int cur = end;
            path.push_back(cur);
            while (cur != start) {
                for (Edge e : G[cur]) {
                    if (dist[e.to] + e.w == dist[cur]) {
                        cur = e.to;
                        path.push_back(cur);
                        break;
                    }
                }
            }
            for (int i = path.size() - 1; i >= 0; --i) {
                cout << path[i];
                if (i != 0) cout << "->";
            }
            cout << endl;
            cout << "最短路径的距离之和为:" << dist[end] << endl;
        }
        case 0: {
            // system("cls");
        }
        }
    } while (a != 0);
        return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值