目录
简介:
- 所有元素都会在插入时自动被排序,需要使用头文件
本质:
- set / multiset 属于关联式容器,底层结构是二叉树实现
set 和 multiset 区别:
- set 不允许容器中有重复的元素
- multiset 允许容器中有重复元素
功能:
- 创建 set 容器以及赋值
构造函数原型:
// 默认构造函数 setst; // 拷贝构造函数 set(const set& st);赋值函数原型:
// 重载 = 操作符 set& operator=(const set& st);
测试代码:
- #include
- using namespace std;
- #include
-
- void PrintSet(const set<int>& s) {
- for (set<int>::const_iterator it = s.begin(); it != s.end(); ++it) {
- cout << *it << " ";
- }
- cout << endl;
- }
-
- void test() {
- set<int>s1;
-
- // 插入数据,只有 insert
- s1.insert(10);
- s1.insert(30);
- s1.insert(20);
-
- // 所有元素在插入时按照从小到大排序
- PrintSet(s1); // 10 20 30
-
- s1.insert(10);
- // 不允许插入重复值
- PrintSet(s1); // 10 20 30
-
- // 拷贝构造
- set<int>s2(s1);
- PrintSet(s2); // 10 20 30
-
- // 重载 = 操作符
- set<int>s3;
- s3 = s2;
- PrintSet(s3); // 10 20 30
- }
-
- int main() {
- test();
- system("pause");
- return 0;
- }
运行结果:
功能:
- 统计 set 容器大小以及交换 set 容器
函数原型:
// 返回容器中元素的数目 size(); // 判断容器是否为空 empty(); // 交换两个集合容器 swap(st);
测试代码:
- #include
- using namespace std;
- #include
-
- void PrintSet(const set<int>& s);
-
- void SetEmpty(const set<int>& s);
-
- void test() {
- set<int>s1;
-
- SetEmpty(s1); // 为空
-
- s1.insert(40);
- s1.insert(10);
- s1.insert(30);
- s1.insert(20);
-
- SetEmpty(s1); // 非空
-
- PrintSet(s1); // 10 20 30 40
-
-
- set<int>s2;
-
- s2.insert(50);
- s2.insert(60);
- s2.insert(70);
- s2.insert(80);
-
- cout << "交换前:" << endl;
- PrintSet(s2);
-
- // 交换 s1 和 s2
- cout << "交换后:" << endl;
- s2.swap(s1);
- PrintSet(s2); // 10 20 30 40
- }
-
- int main() {
- test();
- system("pause");
- return 0;
- }
-
- void SetEmpty(const set<int>& s) {
- if (s.empty()) {
- cout << "set 为空" << endl;
- }
- else {
- cout << "set 非空" << endl;
- }
- }
-
- void PrintSet(const set<int>& s) {
- for (set<int>::const_iterator it = s.begin(); it != s.end(); ++it) {
- cout << *it << " ";
- }
- cout << endl;
- }
运行结果:
功能:
- set 容器进行插入数据和删除数据
函数原型:
// 在容器中插入元素 insert(elem); // 清楚所有元素 clear(); // 删除 pos 迭代器所指的元素,返回下一个元素的迭代器 erase(pos); // 删除区间 [beg, end) 的所有元素,返回下一个元素的迭代器 erase(beg, end); // 删除容器中值为 elem 的元素 erase(elem);
测试代码:
- #include
- using namespace std;
- #include
-
- void PrintSet(const set<int>& s);
-
- void test() {
- set<int>s1;
-
- // insert(elem); 容器中插入元素
- s1.insert(20);
- s1.insert(10);
- s1.insert(30);
- s1.insert(40);
-
- PrintSet(s1); // 10 20 30 40
-
- // erase(pos); 删除迭代器所指向的元素
- s1.erase(s1.begin()); // 删除 10
- PrintSet(s1); // 20 30 40
-
- // erase(beg, end);
- s1.erase(++s1.begin(), --s1.end()); // 双向迭代器
- PrintSet(s1); // 20 40
-
- // erase(elem); 删除容器中值为 elem 的元素
- s1.erase(40);
- PrintSet(s1); // 20
-
- // clear(); 清空所有元素
- s1.clear(); // 清空操作
- PrintSet(s1); // 空
- cout << s1.empty() << endl; // 1
- }
-
- int main() {
- test();
- system("pause");
- return 0;
- }
-
- void PrintSet(const set<int>& s) {
- for (set<int>::const_iterator it = s.begin(); it != s.end(); ++it) {
- cout << *it << " ";
- }
- cout << endl;
- }
运行结果:
功能:
- 对 set 容器进行查找数据以及统计数据
函数原型:
// 查找 key 是否存在,存在返回该元素迭代器,不存在返回 set.end(); find(key); // 统计 key 的元素个数,set 容器返回 0 或 1,multiset 则可以是其他数 count(key);
测试代码:
- #include
- using namespace std;
- #include
-
- void PrintSet(const set<int>& s);
-
- void test() {
- set<int>s1;
-
- s1.insert(20);
- s1.insert(10);
- s1.insert(30);
- s1.insert(40);
-
- // 查找 find(key);
- set<int>::iterator pos = s1.find(10);
- if (pos != s1.end()) {
- cout << "找到了" << *pos << endl;
- }
- else {
- cout << "未找到" << endl;
- }
-
- // 统计 count(key);
- int sum1 = s1.count(10);
- cout << sum1 << endl; // 1
-
- int sum2 = s1.count(50);
- cout << sum2 << endl; // 0
- }
-
- int main() {
- test();
- system("pause");
- return 0;
- }
-
- void PrintSet(const set<int>& s) {
- for (set<int>::const_iterator it = s.begin(); it != s.end(); ++it) {
- cout << *it << " ";
- }
- cout << endl;
- }
运行结果:
区别:
- set 不可以插入重复元素,multiset 可以
- set 插入数据的同时可以返回插入结果,表示插入是否成功
- multiset 不会检查数据,所以可以插入重复数据
测试代码:
- #include
- using namespace std;
- #include
-
- void test() {
- set<int>s1;
-
- // set 插入成功会返回插入结果
- pair
int>::iterator, bool> ret = s1.insert(10); -
- if (ret.second) {
- cout << "第一次插入成功" << endl;
- }
- else {
- cout << "插入失败" << endl;
- }
-
- ret = s1.insert(10);
-
- if (ret.second) {
- cout << "第一次插入成功" << endl;
- }
- else {
- cout << "插入失败" << endl;
- }
-
- // multiset 允许插入重复值
- multiset<int>s2;
- s2.insert(10);
- s2.insert(10);
-
- for (multiset<int>::iterator it = s2.begin(); it != s2.end(); ++it) {
- cout << *it << " "; // 10 10
- }
- cout << endl;
- }
-
- int main() {
- test();
- system("pause");
- return 0;
- }
运行结果:
功能:
- 成对出现的数据,利用对组可以返回两个数据
两种创建方式:
不需要包含头文件
pairp (value1, value2) ; pairp = make_pair(value1, value2);
测试代码:
- #include
- #include
- using namespace std;
-
- void test() {
- // 第一种方式
- pair
int>p1("李华", 18); -
- // 获取第一个数据
- cout << p1.first << endl;
- // 获取第二个数据
- cout << p1.second << endl;
-
- // 第二种方式
- pair
int>p2 = make_pair("张三", 20); -
- // 获取第一个数据
- cout << p2.first << endl;
- // 获取第二个数据
- cout << p2.second << endl;
- }
-
- int main() {
- test();
- system("pause");
- return 0;
- }
运行结果:
set 容器默认排序规则为从小到大,掌握如何更改排序规则
- 运用仿函数,改变排序规则
测试代码:
- #include
- using namespace std;
- #include
-
- class MyCompare {
- public:
- bool operator()(int value1, int value2)const {
- return (value1 > value2);
- }
- };
-
- void test() {
-
- set<int>s1;
-
- s1.insert(10);
- s1.insert(30);
- s1.insert(50);
- s1.insert(20);
- s1.insert(40);
- // 默认从小到大
- for (set<int>::iterator it1 = s1.begin(); it1 != s1.end(); ++it1) {
- cout << *it1 << " "; // 10 20 30 40
- }
- cout << endl;
-
- // 指定排序规则,从大到小
- set<int, MyCompare>s2;
-
- s2.insert(10);
- s2.insert(30);
- s2.insert(50);
- s2.insert(20);
- s2.insert(40);
-
- for (set<int, MyCompare>::iterator it2 = s2.begin(); it2 != s2.end(); ++it2) {
- cout << *it2 << " "; // 40 30 20 10
- }
- cout << endl;
- }
-
- int main() {
- test();
- system("pause");
- return 0;
- }
运行结果:
仿函数更改自定义数据类型排序规则(必须要指定排序规则)
- #include
- #include
- using namespace std;
- #include
-
- class Person {
- public:
- Person(string name, int age) :m_Name(name), m_Age(age) {}
-
- string m_Name;
- int m_Age;
- };
-
- class MyCompare {
- public:
- bool operator()(Person p1, Person p2)const {
- return (p1.m_Age < p2.m_Age);
- }
- };
-
- void test() {
- // 自定义数据类型都需要指定排序规则
- set
Person_Set; -
- Person p1("李四", 20);
- Person p2("张三", 18);
- Person p3("王五", 19);
- Person p4("李华", 17);
-
- Person_Set.insert(p1);
- Person_Set.insert(p2);
- Person_Set.insert(p3);
- Person_Set.insert(p4);
- // set 默认排序(小到大),编译器不知道怎么排序,自定义的数据类型都需要指定排序规则
- for (set
::iterator it = Person_Set.begin(); it != Person_Set.end(); ++it) { - cout << "name:" << it->m_Name << " " << "age:" << (*it).m_Age << endl;
- }
- }
-
- int main() {
- test();
- system("pause");
- return 0;
- }
运行结果: