c++ hashset的用法_C++ set用法(STL set用法)详解

本文介绍了C++中set容器的使用,包括在创建学生分配到课程组的示例中如何利用set。文章讨论了如何避免对象拷贝,使用set的插入操作,并展示了如何为满足最小课程数目的学生分配课程。此外,还涉及了如何通过STL算法检查和调整学生选课情况,并输出课程信息。
摘要由CSDN通过智能技术生成

是时候了解一下 set 容器的用法了。我们把 vector、set 和 map 容器组合在一起来创建一个示例,并且会介绍一种新的有用算法。

在这个示例中,你会将学习不同学科的学生分配到一组。每个学生都必须学习指定的最小数目的学科。每个学习特定学科的学生都被保存到 set 容器中,因为一个学生只能在一门特定课程中出现一次。这个示例不会特别有效率。在本例中会大量地拷贝学生对象,这里可能无关紧要,但是如果用来表示学生的对象很大,这就很重要了,因为这会产生很多开销。本章后面会介绍如何消除对象的副本。本例的基本工作流程如图 1 所示。

图 1 用 set 容器表示课程组

下面的 using 结构定义了一些本例中使用的别名:

using std::string;

using Distribution = std::uniform_int_distribution;

using Subject = string; // A course subject

using Subjects = std::vector; // A vector of subjects

using Group = std::set<:weak_ptr>, std::owner_less<:weak_ptr>>>; // A student group for a subject

using Students = std::vector<:shared_ptr>>; // All the students

using Course = std::pair; // A pair representing a course

using Courses = std::map; // The container for courses

这些别名不是必需的,但它们可以使代码更加简洁。

首先,我们需要定义一个表示学生的类。Student 类的定义很简单,我们可以简单地在 Student.h 中定义这个类,例如:

// Student.h

// Student class definition for Ex5_02 - unchanged from Ex5_01

#ifndef STUDENT_H

#define STUDENT_H

#include // For string class

#include // For output streams

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)){} // Move constructor

Student(const Student& student) : first(student.first), second(student.second){} // Copy constructor

Student() {} // Default constructor

// Less-than operator

bool operator

{

return second < student.second || (second == student.second && first < student.first);

}

friend std::ostream& operator<

};

// Insertion operator overload

inline std::ostream& operator<

{

out << student.first + " " + student.second;

return out;

}

#endif

Student 只有两个数据成员,用来保存学生的名和姓。Student 对象最初保存在 vector 容器中,因此需要定义默认的构造函数。这里有拷贝构造函数和移动构造函数,后者可以在适当时避免对象的副本。因为 Student 会被保存在 set 容器中,用来表示不同学科的课程,所以需要定义小于运算符。这里用友元函数重载了一个流插入运算符来辅助输出。

创建Student对象

程序需要一定数量的 Student 对象,为了避免费力地从键盘输入数据,我们可以通过组合姓名的方式来创建 Student 对象的 vector 容器:

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(first, second));

}

return students;

}

这里用 using 语句为 Student 对象的 vector 容器定义了一个别名 Students。函数用两个数组中的元素组合出了所有可能的姓名,在局部 students 容器中创建 Student 对象。外循环对名进行迭代,内循环在给定的名后添加姓。因此我们会有 25 名学生。我们可以按如下方式调用函数来创建 students:

Students students = create_students();

vector 容器有移动构造函数,因此编译器会移动而不是拷贝返回的局部 students。上面的语句会调用 vector 的移动赋值运算符来移动 create_students() 的返回值,因此不会拷贝这个 vector 及

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值