数据结构设计预习三

1.问题定义

a.能够提供按参赛学校查询参赛团队(或根据赛事类别查询参赛团队),即,根据提示输入参赛学校名称(赛事类别),若查找成功,输出该学校参赛的(该赛事类别的)所有团队的基本信息,输出的参赛团队按赛事类别有序输出。(排序算法可从选择排序、插入排序、希尔排序、归并排序、堆排序中任意选择,并为选择算法的原因做出说明。)

b.为省赛现场设计一个决赛叫号系统。所有参赛队按赛事组织文件中的赛事类别分到9个决赛室,决赛室按顺序叫号,被叫号参赛队进场,比赛结束后,下一参赛队才能进赛场。请模拟决赛叫号系统,演示省赛现场各决赛室的参赛队进场情况。(模拟时,要能直观展示叫号顺序与进场秩序一致)

c.赛事系统为参赛者提供赛地的校园导游程序,为参赛者提供各种路径导航的查询服务。以我校长山校区提供比赛场地为例,(请为参赛者提供不少于10个目标地的导航。可为参赛者提供校园地图中任意目标地(建筑物)相关信息的查询;提供任意两个目标地(建筑物)的导航查询,即查询任意两个目的地(建筑物)之间的一条最短路径。

2、问题分析

在a中首先我们可以用了哈希表的查找方式。std::map<std::string, std::vector<Team>>来创建一个映射,将参赛学校名称与团队向量关联起来。

  在遍历给定的团队列表时,通过检查团队的学校是否与输入的学校名称匹配,将符合条件的团队添加到相应赛事类别的团队向量中。这里通过使用schoolTeams[team.eventCategory].push_back(team)将符合条件的团队添加到schoolTeams映射中。

  最后,代码根据schoolTeams映射是否为空来判断是否找到符合条件的团队。如果映射为空,则输出"未找到该学校参赛的团队!"的提示信息。否则,遍历按赛事类别分组的团队信息,输出参赛团队的基本信息。

关于b,

需要考虑使用多种元素进行实现:

  • 每个参赛队需要被量化并装配到所属赛事类别的队列中。
  • 对于每个决赛室,需要一个存储-container来存放该组内所有的参赛队,并决定先后顺序。
  • 叫号系统需要是一个具有时序,并按规定顺序调用各组队列/容器中的参赛队的程序。
  • 考虑到并发性和可扩展性,建议将各项任务设为多线程进行执行。
  1. 如何实现决赛叫号系统?

实现决赛叫号系统的基本思路如下:

  • 1)设置9个决赛室,每个室内设定一个队列(FIFO)分别存储相应赛事类别参赛队;
  • 2)每次比赛开始时,将所有参赛队划分到对应队列中,并根据规定顺序进入调度状态;
  • 3)准备好结果显示界面,在进出场比赛时更新参赛队状态;
  • 4)按照规定顺序分别从9个队列中取出每个参赛队,显示其进出场时间,并判断是否还有下一个参赛队可以进场;
  • 5)如果当前所有室内参赛队已经进出完毕,则结束整个比赛。

对于c

本次任务的校园导游程序应该实现以下基本功能:

  • 提供地图定位服务,可以为参赛者在校园地图上选取目标位置。
  • 提供路径规划,查询任意两个目的地之间最短的行驶路线。
  • 支持多种查询方式,包括校园地图上地点搜索、建筑物功能介绍查询等。
  • 显示相关指示和提示信息,如路径长度、时间预算等。
  1. 校园导游程序需要哪些元素来实现?
  • 需要利用地图软件提供的地理位置信息完成地图显示、目标定位等功能。
  • 需要对校园地图的路径网络进行建模,并利用起点和终点之间的路径计算公式计算最小直线距离。
  • 为了提供更好的用户体验,考虑使用图形化界面,并引入多种交互手段(如按钮、下拉框等)操作以方便用户。
  • 对于各个建筑物,应当提供其名称、图片及相关介绍资料等。

以下是部分代码:(注:代码不是连续的,且并不完整)

// 按照参赛学校名称查找队伍

void searchBySchool(const std::vector<Team>& teams) {

    std::string school;

    std::cout << "请输入要查找的参赛学校名称:";

    std::cin >> school;

    std::map<std::string, std::vector<Team>> schoolTeams;// 创建一个映射,将参赛学校名称与团队向量关联起来

    for (const Team& team : teams) {// 遍历给定的团队列表

        if (team.school == school) {// 检查团队的学校是否与输入的学校名称匹配

            schoolTeams[team.eventCategory].push_back(team);// 将符合条件的团队添加到相应赛事类别的团队向量中

        }

    }

    if (schoolTeams.empty()) {

        std::cout << "未找到该学校参赛的团队!" << std::endl;// 检查是否找到符合条件的团队

    }

    else {

        std::cout << "该学校参赛的团队基本信息:" << std::endl;// 输出未找到团队的提示信息

        for (auto& entry : schoolTeams) {// 遍历按赛事类别分组的团队信息

            std::cout << "赛事类别:" << entry.first << std::endl;

            std::cout << "参赛团队信息:" << std::endl;

            const std::vector<Team>& teams = entry.second;// 获取当前赛事类别下的团队向量

            for (const Team& team : teams) {// 遍历当前赛事类别下的团队

                std::cout << "参赛队编号:" << team.teamNumber << ",参赛作品名称:" << team.projectName << std::endl;

            }

        }

    }

}

//————————————————————————-----------------决赛室代码

// 参赛队伍的结构体

struct Teams {

    int teamIds;

    string projectNames;

    string schools;

    string categorys;

    string participantss;

    string coachs;

};

// 用于比较参赛队伍的辅助函数

bool compareTeams(const Teams& team1, const Teams& team2) {

    return team1.teamIds < team2.teamIds;

}

// 决赛室叫号系统类

class FinalsCallSystem {

private:

    map<string, vector<Teams>> categoryTeams;  // 按赛事类别存储参赛队伍

    vector<queue<Teams>> finalsRooms;          // 存储决赛室及其队伍队列

public:

    // 从文件中读取参赛队伍信息

    void readTeamInfo(const string& filename) {

        ifstream file(filename);

        string line;

        while (getline(file, line)) {

            stringstream ss(line);

            Teams team;

            ss >> team.teamIds >> team.projectNames >> team.schools >> team.categorys >> team.participantss >> team.coachs;

            categoryTeams[team.categorys].push_back(team);

        }

        file.close();

        // 将每个赛事类别的参赛队伍按队伍编号排序

        for (auto& categorys : categoryTeams) {

            sort(categorys.second.begin(), categorys.second.end(), compareTeams);

        }

    }

    // 模拟决赛叫号过程

    void simulateFinals() {

        int numRooms = 9;  // 决赛室数量

        int roomNumber = 1;  // 当前决赛室编号

        // 计算每个决赛室应分配的赛事类别数量

        int numCategoriesPerRoom = categoryTeams.size() / numRooms;

        int remainingCategories = categoryTeams.size() % numRooms;

        auto categoryIter = categoryTeams.begin();

        // 初始化决赛室容器

        finalsRooms.resize(numRooms);

        // 分配赛事类别到决赛室

        for (int i = 0; i < numRooms; i++) {

            int numCategories = numCategoriesPerRoom;

            if (remainingCategories > 0) {

                numCategories++;

                remainingCategories--;

            }

            cout << "决赛室 " << roomNumber << ":";

            // 将赛事类别的参赛队伍分配到当前决赛室

            for (int j = 0; j < numCategories; j++) {

                const auto& categorys = *categoryIter;

                const vector<Teams>& teams = categorys.second;

                // 输出当前赛事类别的参赛队伍

                for (const auto& team : teams) {

                    finalsRooms[i].push(team);

                    cout << team.teamIds << " ";

                }

                categoryIter++;

            }

            cout << endl;

            roomNumber++;

        }

        cout << "模拟比赛开始:" << endl;

        // 模拟比赛过程

        while (!finalsRooms.empty()) {

            for (int i = 0; i < finalsRooms.size(); i++) {

                if (!finalsRooms[i].empty()) {

                    const Teams& team = finalsRooms[i].front();

                    cout << "决赛室 " << (i + 1) << ":参赛队伍 " << team.teamIds << " 进场" << endl;

                    finalsRooms[i].pop();

                }

            }

        }

        cout << "比赛结束。" << endl;

    }

};

void ShortestPath(int source, int destination) {

    // 使用优先队列来选择下一个要处理的节点,按照距离排序

    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;

    // 存储从起点到每个节点的最短距离

    vector<int> distance(campusMap.size(), INF);

    // 存储每个节点在最短路径中的前一个节点

    vector<int> previous(campusMap.size(), -1);

    // 将起点加入优先队列,并将其距离设置为0

    pq.push({ 0, source });

    distance[source] = 0;

    // 开始寻找最短路径

    while (!pq.empty()) {

        int u = pq.top().second;// 获取优先队列中距离最小的节点

        int dist = pq.top().first;// 获取距离

        pq.pop();

        // 弹出队列中的节点

        // 如果当前节点的距离大于已知的最短距离,则忽略

        if (dist > distance[u]) {

            continue;

        }

        // 遍历当前节点的所有邻居节点

        for (auto neighbor : campusMap[u].neighbors) {

            int v = neighbor.first;

            int weight = neighbor.second;

            // 如果经过当前节点到达邻居节点的距离更短,则更新最短距离和前一个节点

            if (distance[u] + weight < distance[v]) {

                distance[v] = distance[u] + weight;// 更新最短距离

                previous[v] = u;// 更新前一个节点

                pq.push({ distance[v], v });// 将邻居节点加入优先队列,以便后续处理

            }

        }

    }

    // 检查是否存在路径

    if (distance[destination] == INF) {

        cout << "No path exists from " << campusMap[source].name << " to " << campusMap[destination].name << endl;

        return;

    }

    // 构建路径

     // 现在可以通过previous数组来构建最短路径

    // 根据目标节点的previous数组回溯路径,直到达到起点

    vector<int> path;

    int current = destination;

    while (current != -1) {

        path.push_back(current);

        current = previous[current];

    }

    reverse(path.begin(), path.end());// 最短路径是倒序的,所以需要反转它

    // 打印地图

    cout << "Campus Map:" << endl;

    cout << "北门1——100————海韵湖2" << endl;

    cout << "   |200                \\" << endl;

    cout << "   |                   \\" << endl;

    cout << "  计算机学院3           \\" << endl;

    cout << "        |                 \\900" << endl;

    cout << "        | 500              \\" << endl;

    cout << "        |                    \\" << endl;

    cout << "        |                     \\" << endl;

    cout << "   文理大楼4—100—笃学楼5—50—图书馆6" << endl;

    cout << "         /                       \\" << endl;

    cout << "        / 50                     \\100" << endl;

    cout << "     明德楼7 ————900————   东食堂8" << endl;

    cout << "     /400                             \\" << endl;

    cout << "   /                                   \\400" << endl;

    cout << "西食堂9——200— —— ———————— 体育馆10" << endl;

    cout << endl;

    // 输出路径信息// 输出最短路径

    cout << "Shortest Path from " << campusMap[source].name << " to " << campusMap[destination].name << ":" << endl;

    for (int i = 0; i < path.size(); i++) {

        cout << campusMap[path[i]].name;

        if (i != path.size() - 1) {

            cout << " -> ";

        }

    }

    cout << endl;

    cout << "Total Distance: " << distance[destination] << endl;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值