前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >STL-vector,map,set集合应用案例

STL-vector,map,set集合应用案例

作者头像
用户9831583
发布2022-06-16 15:09:58
1800
发布2022-06-16 15:09:58
举报
文章被收录于专栏:码出名企路

具体案例:

学校需要将不同学科的学生分配到一组。每个学生都必须学习指定的最小数目的学科。每个学习特定学科的学生都被保存到 set容器中,因为一个学生只能在一门特定课程中出现一次。

基本流程:

第一步:学生类

代码语言:javascript
复制
  #ifndef STUDENT_H
    #define STUDENT_H
    #include <string>                                
    #include <ostream>    

    //两个成员函数,保存姓,名                        
    class Student
    {
        private:
            std::string first {};
            std::string second {};
        public:
            Student(const std::string& name1, const std::string& name2) : first (name1), second (name2){}
            //移动构造
            Student(Student&& student) : first(std::move(student.first)),
                             second(std::move(student.second)){}
            //复制构造
            Student(const Student& student) : first(student.first), second(student.second){}                  // Copy constructor
            Student() {}                                                                                      // Default constructor
          
            bool operator<(const Student& student) const
            {
                return second < student.second || (second == student.second && first < student.first);
            }
            //友元函数重载了一个流插入运算符来辅助输出
            friend std::ostream& operator<<(std::ostream& out, const Student& student);
    };
    
    inline std::ostream& operator<<(std::ostream& out, const Student& student)
    {
        out << student.first + " " + student.second;
        return out;
    }
    #endif

第二步:输出类

代码语言:javascript
复制
#ifndef LIST_COURSE_H
    #define LIST_COURSE_H
    #include <iostream>                          
    #include <string>                              
    #include <set>                              
    #include <algorithm>                          
    #include <iterator>                        
    #include "s.h"

    using Subject = std::string;                  
    
    using Group = std::set<std::weak_ptr<Student>, std::owner_less<std::weak_ptr<Student>>>;  
    
    using Course = std::pair<Subject, Group>;      
    
    class List_Course
    {
    public:
        void operator()(const Course& course)
        {
            std::cout << "\n\n" << course.first << "  " << course.second.size() << " students:\n  ";
            std::copy(std::begin(course.second), std::end(course.second),
                         std::ostream_iterator<std::weak_ptr<Student>>(std::cout, "  "));
        }
    };
    inline std::ostream& operator<<(std::ostream& out, const std::weak_ptr<Student>& wss)
    {
        out << *wss.lock();
        return out;
    }
    #endif

第三步:主函数

代码语言:javascript
复制
    #include <iostream>                        
    #include <string>                                
    #include <map>                                  
    #include <set>                                
    #include <vector>                                
    #include <random>                              
    #include <algorithm>            // For for_each(), count_if()
    #include <memory>               // For shared_ptr and weak_ptr
    #include "s.h"
    #include "l.h"

    using std::string;

    using Distribution = std::uniform_int_distribution<size_t>;

    using Subject = string;              
    using Subjects = std::vector<Subject>;    
    
    //学生集合对象别名
    using Group = std::set<std::weak_ptr<Student>, std::owner_less<std::weak_ptr<Student>>>;  
    
    //定义学生类别名
    using Students = std::vector<std::shared_ptr<Student>>;    
   
    using Course = std::pair<Subject, Group>;  
    //课程容器              
    using Courses = std::map<Subject, Group>;        
   //随机数创建器
   //分布对象是一个函数对象,它可以创建分布内的随机数,可以将随机数创建器对象作为参数传给分布对象的成员函数opemtor()()
    static std::default_random_engine gen_value;
   
    // 创建对象
    Students create_students()
    {
        Students students;
        string first_names[]{"Ann", "Jim", "Eve", "Dan", "Ted"};
        string second_names[]{"Smith", "Jones", "Howe", "Watt", "Beck"};
        for(const auto& first : first_names)
            for(const auto& second : second_names)
            {
                students.emplace_back(std::make_shared<Student>(first, second));
            }
        return students;
    }

    // 为指定学科随机创 建一组学生
    //第一个参数是一个包含 Student 对象的 vector,第二个参数是组中要求的学生个数,
    //最后一个参数是分布的索引值,用来选择随机创建的学生
    Group make_group(const Students& students, size_t group_size,
                                          Distribution& choose_student)
    {
        Group group;  
        size_t count{};                  
        std::pair<Group::iterator, bool> pr;  
        
        while(count < group_size)
        {  //如果插入的元素已经在容器中,成员函数 insert() 不会插入新的对象。
            
          pr=group.insert(students[choose_student(gen_value)]);//???????????????????
            if(pr.second)
                ++count;
        }
        //会通过移动而不是复制的方式返回局部的 group 对象
        return group;
    }


    int main()
    {
        Students students = create_students();
        //学科定义
        // subjects 是一个包含 string 对象的 vector 容器。
        Subjects subjects {"Biology", "Physics", "Chemistry", "Mathematics",
                            "Astronomy","Drama", "Politics", "Philosophy", "Economics"};
       //一个包含全部课程的容器
        Courses courses;     //pair<string,set<>>    
        
         //需要学习的最少学科数
        size_t min_subjects{4};    
        //每组的最少学生数都设为相同的 值
        size_t min_group{min_subjects};  
        //每个学科组的最大学生数就是一个平均值
        size_t max_group{(students.size()*min_subjects) / subjects.size()};

        //一个用来在均匀分布中选择随机值的函数对象:
        //创建 min_group〜max_group 范围内的随机数
        Distribution group_size{min_group, max_group};
        //创建students中的有效索引值。
        Distribution choose_student{0, students.size() - 1};  
        
        //为 course 容器填充了一些表示课程信息的元素
        for(const auto& subject : subjects)
            courses.emplace(subject, make_group(students, group_size(gen_value), choose_student));

        //创建 subjects 容器的一个有效索引值,可以用它来选择课程
        Distribution choose_course{0, subjects.size() - 1};    

      //检查每个学生是否都选了足够的课程
      //如果没有选择足够的课程,为他们申请其他的课程
        for(const auto& student : students)
        {    
            //count_if() 算法用来计算每个学生已报名参加的课程数
            //count_if() 的第三个参数必须是一个二元函数,它的返回值必须是布尔值或其他可以隐式转换为布尔型的值
            size_t course_count = std::count_if(std::begin(courses), std::end(courses),
                         [&student](const Course& course)
            {  return course.second.count(student); });

            if(course_count >= min_subjects)
                    continue;            
    
            size_t additional{min_subjects - course_count};      
            if(!course_count)                                      
                std::cout << *student << " is work-shy, having signed up for NO Subjects!\n";
            else                                                
                std::cout << *student << " is only signed up for " << course_count << " Subjects!\n";

            std::cout << "Registering " << *student << " for " << additional
                  << " more course" << (additional > 1 ? "s" : "") << ".\n\n";
            //为这些学生申请新的课程,直到他们申请的课程数目满足要求
            while(course_count < min_subjects)
                if((courses.find(subjects[choose_course(gen_value)])->second.insert(student)).second)
                         ++course_count;
        }
        // 输出课程
        std::for_each(std::begin(courses), std::end(courses), List_Course());
        std::cout << std::endl;
    }

结果显示:


本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-03-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码出名企路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档