- set 容器
- set 构造和赋值
- set 大小和交换
- set 插入和删除
- set 查找和统计
- pair 对组的使用
- set 和 multiset 的区别
- set 排序
- map 容器
- map 构造和赋值
- map 大小和交换
- map 插入和删除
- map 查找和统计
- map 排序
- STL 案例 -- 员工分组
特点
所有元素在插入时自动被排序
本质
set/multiset 属于关联式容器,底层结构用二叉树实现
set 和 multiset 的区别
- set 不允许容器中有重复的元素
- multiset 允许容器中有重复的元素
函数原型
1. 构造函数
- set
s; // 默认构造函数 - set
s1(const set &s); // 拷贝构造函数
2. 赋值函数
- set& operator=(const set &s); // 重载赋值运算符
#includeset 大小和交换using namespace std; #include // 打印 set 容器内元素 void PrintSet(set &s) { for (set ::iterator it = s.begin(); it != s.end(); it++) { cout << *it << " "; } cout << endl; } int main() { // 1. 构造函数 set s; // 插入数据 -- set 容器只 insert 方式插入数据 s.insert(1); s.insert(7); s.insert(4); // 打印容器内元素 PrintSet(s); // 1 4 7 // 2. 拷贝构造函数 set s1(s); PrintSet(s1); // 1 4 7 // 3. 赋值操作 set s2; // 构造函数 s2 = s1; PrintSet(s2); // 1 4 7 system("pause"); return 0; }
函数原型
- empty(); // 判断容器是否为空
- size(); // 返回容器大小
- s.swap(s1); // 将容器 s1 和容器 s 中的元素互换
#includeset 插入和删除using namespace std; #include // 打印 set 容器内元素 void PrintSet(set &s) { for (set ::iterator it = s.begin(); it != s.end(); it++) { cout << *it << " "; } cout << endl; } int main() { // 构造函数 set s; // 1. 判断容器是否为空 if (s.empty()) { cout << "容器为空!" << endl; } // 插入数据 -- set 容器只 insert 方式插入数据 s.insert(1); s.insert(7); s.insert(4); // 2. 打印容器大小 cout << "容器大小为:" << s.size() << endl; // 3. 交换二个不同的容器 // 准备容器 s1 set s1; s1.insert(6); s1.insert(1); s1.insert(9); // 分别打印二个容器 PrintSet(s); // 1 4 7 PrintSet(s1); // 1 6 9 // 交换 s1.swap(s); // 重新分别打印二个容器 PrintSet(s); // 1 6 9 PrintSet(s1); // 1 4 7 system("pause"); return 0; }
函数原型
- insert(elem); // 在容器中插入元素
- erase(const_iterator pos); // 删除迭代器指向位置 pos 的元素,返回下一个元素的迭代器
- erase(const_iterator start, const_iterator end); // 删除迭代器指向某区间的元素,返回下一个元素的迭代器
- erase(elem); // 删除容器中值为 elem 的元素
- clear(); // 清空容器
#includeset 查找和统计using namespace std; #include // 打印 set 容器内元素 void PrintSet(set &s) { for (set ::iterator it = s.begin(); it != s.end(); it++) { cout << *it << " "; } cout << endl; } int main() { // 构造函数 set s; // 1. 插入数据 s.insert(1); s.insert(7); s.insert(4); s.insert(9); s.insert(2); PrintSet(s); // 1 2 4 7 9 // 2. 删除迭代器指向位置 pos 的元素 s.erase(++s.begin()); PrintSet(s); // 1 4 7 9 // 3. 删除迭代器指向区间的元素 s.erase(++s.begin(), --s.end()); PrintSet(s); // 1 9 // 4. 删除容器中值为 elem 的元素 s.erase(1); PrintSet(s); // 9 // 5. 清空容器 s.clear(); PrintSet(s); // 空 system("pause"); return 0; }
函数原型
- find(elem); // 查找元素 elem 是否存在,存在则返回该元素的迭代器,否则返回 set.end();
- count(elem); // 统计元素 elem 的个数
#includepair 对组的使用using namespace std; #include // 打印 set 容器内元素 void PrintSet(set &s) { for (set ::iterator it = s.begin(); it != s.end(); it++) { cout << *it << " "; } cout << endl; } int main() { // 构造函数 set s; // 插入数据 s.insert(1); s.insert(7); s.insert(4); s.insert(9); s.insert(2); PrintSet(s); // 1 2 4 7 9 set ::iterator it = s.find(9); // 1. 查找元素是否存在 if (it != s.end()) { cout << "元素存在:" << *it << endl; // 元素存在:9 } else { cout << "元素不存在" << endl; } // 2. 统计元素的个数 -- 元素统计的结果只会出现 0 或 1;因为 set 容器中不允许出现重复元素 cout << s.count(1) << endl; // 1 cout << s.count(100) << endl; // 0 system("pause"); return 0; }
功能
成对出现的数据,利用对组可以返回二个数据
二种创建方式
- pair
p(value1, value2); - pair
p = make_pair(value1, value2);
#includeset 和 multiset 的区别using namespace std; #include int main() { // 1. 第一种方式 pair p("Su", 19); // 取数据,p.first 和 p.second 分别为第一个和第二个元素 cout << "姓名:" << p.first << " 年龄:" << p.second << endl; // 姓名:Su 年龄:19 // 2. 第二种方式 pair p1 = make_pair("Mei", 19); cout << "姓名:" << p1.first << " 年龄:" << p1.second << endl; // 姓名:Mei 年龄:19 system("pause"); return 0; }
区别
- set 不可以重复插入数据,而 multiset 可以
- set 插入的时候会返回插入的结果,表示插入是否成功
- multiset 不会检测插入的结果,因此可以插入重复的数据
#includeset 排序using namespace std; #include // 打印 set 容器内元素 void PrintSet(set &s) { for (set ::iterator it = s.begin(); it != s.end(); it++) { cout << *it << " "; } cout << endl; } int index = 0; void Check(pair ::iterator, bool> &ret) { index++; if (ret.second) { cout << "第 " << index << " 次插入成功!" << endl; } else { cout << "第 " << index << " 次插入失败~" << endl; } } int main() { // 构造函数 set s; // 1. set 容器不允许插入重复值 // 测试第一次插入 1 pair ::iterator, bool> ret = s.insert(1); Check(ret); // 第 1 次插入成功! // 测试第二次插入 1 ret = s.insert(1); Check(ret); // 第 2 次插入失败~ // 2. multiset 容器允许插入重复值 multiset ms; ms.insert(1); ms.insert(1); ms.insert(1); // 打印元素 for (multiset ::iterator it = ms.begin(); it != ms.end(); it++) { cout << *it << " "; // 1 1 1 } cout << endl; system("pause"); return 0; }
1. 内置数据类型
#includeusing namespace std; #include // 打印 set 容器内元素 void PrintSet(set &s) { for (set ::iterator it = s.begin(); it != s.end(); it++) { cout << *it << " "; } cout << endl; } // 为自定义排序后的容器 set 实现打印函数 void PrintSet1(set &s) { for (set ::iterator it = s.begin(); it != s.end(); it++) { cout << *it << " "; } cout << endl; } class MyCompare { public: // 重载仿函数 bool operator()(int num1, int num2) { return num1 > num2; } }; int main() { set s; s.insert(3); s.insert(1); s.insert(2); s.insert(7); // 默认排序 -- 升序 PrintSet(s); // 1 2 3 7 // 要求实现:降序 set s1; s1.insert(3); s1.insert(1); s1.insert(2); s1.insert(7); PrintSet1(s1); // 7 3 2 1 system("pause"); return 0; }
2. 自定义数据类型
#includeusing namespace std; #include #include class Person { public: Person(string name, int age) { this->Name_ = name; this->Age_ = age; } string Name_; int Age_; }; class MyCompare { public: // 重载仿函数 bool operator()(const Person &p1, const Person &p2) { return p1.Age_ < p2.Age_; } }; // 为自定义排序后的容器 set 实现打印函数 void PrintSet(set &s) { for (set ::iterator it = s.begin(); it != s.end(); it++) { cout << "姓名:" << (*it).Name_ << " 年龄:" << (*it).Age_ << endl; } } int main() { // 自定义排序容器 -- 年龄升序 set s; // 创建数据 Person p1("Su", 19); Person p2("Ku", 39); Person p3("Iu", 29); Person p4("Pu", 49); // 插入数据 s.insert(p1); s.insert(p2); s.insert(p3); s.insert(p4); // 输出容器内元素 PrintSet(s); // outputs:姓名:Su 年龄:19 // 姓名:Iu 年龄:29 // 姓名:Ku 年龄:39 // 姓名:Pu 年龄:49 system("pause"); return 0; }
3. 报错代码
#includemap 容器using namespace std; #include #include class Person { public: Person(string name, int age) { this->Name_ = name; this->Age_ = age; } int getAge() { return Age_; } string getName() { return Name_; } private: string Name_; int Age_; }; class MyCompare { public: // 重载仿函数 bool operator()(const Person &p1, const Person &p2) { return (p1.getAge() < p2.getAge()); } }; // 为自定义排序后的容器 set 实现打印函数 void PrintSet(set &s) { for (set ::iterator it = s.begin(); it != s.end(); it++) { cout << "姓名:" << (*it).getName() << " 年龄:" << (*it).getAge() << endl; } cout << endl; } int main() { // 自定义排序容器 -- 年龄升序 set s; // 创建数据 Person p1("Su", 19); Person p2("Ku", 39); Person p3("Iu", 29); Person p4("Pu", 49); // 插入数据 s.insert(p1); s.insert(p2); s.insert(p3); s.insert(p4); // 输出容器内元素 PrintSet(s); system("pause"); return 0; }
概念
- map 中所有元素都是 pair 对组
- pair 中第一个元素为 key(键值),起到索引作用;第二个元素为 value(实值)
- 所有元素都会根据元素的键值自动排序
本质
map/multimap 属于关联式容器,底层结构用二叉树实现
优点
可以根据 key 值快速找到 value 值
map 和 multimap 的区别
- map 不允许容器中有重复的 key 元素
- multimap 允许容器中有重复的 key 元素
函数原型
1. 构造函数
- map
m; // map 默认构造函数 - map
m1(const map &m); // 拷贝构造函数
2. 赋值函数
- map& operator=(const map &m); // 重载赋值运算符
#includemap 大小和交换using namespace std; #include
函数原型
- empty(); // 判断容器是否为空
- size(); // 返回容器的大小
- m1.swap(m); // 将容器 m1 和 m 的元素互换
#includemap 插入和删除using namespace std; #include
函数原型
- insert(elem); // 在容器中插入元素
- erase(const_iterator pos); // 删除迭代器指向位置 pos 的元素,返回下一个元素的迭代器
- erase(const_iterator start, const_iterator end); // 删除迭代器指向某区间的元素,返回下一个元素的迭代器
- erase(key); // 删除容器中键为 key 的元素
- clear(); // 清空容器
#includemap 查找和统计using namespace std; #include
函数原型
- find(key); // 查找键 key 是否存在,存在则返回该键对应元素的迭代器,否则返回 map.end();
- count(key); // 统计元素 key的个数
#includemap 排序using namespace std; #include
#includeSTL 案例 – 员工分组using namespace std; #include
案例描述
- 公司新招聘的 10 个员工(ABCDEFGHIJ)进入公司后分配到不同部门
- 员工信息:姓名、工资;部门分为:策划、美术、研发
- 随机给 10 名员工分配部门和工资
- 通过 multimap 进行信息的插入(key - 部门编号,value - 员工)
- 分部门显示员工信息
实现步骤
- 创建 10 名员工,放到 vector 中
- 遍历 vector 容器,取出每个员工,进行随机分组
- 分组后,将员工编号作为 key,具体员工作为 value,放到 multimap 容器中
- 分部门显示员工信息
#includeusing namespace std; #include #include #include #include



