C++学习 --- STL常用容器之set容器
7、set/multiset 容器
7.1、set基本概念
简介:
-
所有所有元素都会在插入时自动被排序
本质:
-
set/multiset属于关联式容器,底层结构是用二叉树实现
set和multiset区别:
-
set不允许容器中有重复的元素
-
multiset允许容器中有重复的元素
7.2、set构造和赋值
功能描述:创建set容器以及赋值
#include <iostream> #include <set> using namespace std; /* set<T> st;//默认构造函数; set(const set & st); //拷贝构造函数 set & operator=(const set &st);//重载等号操作符 */ //set容器的构造和赋值 void printSet(set<int> &s) { for (set<int>::iterator it = s.begin(); it != s.end();it++) { cout << *it << " "; } cout << endl; } void test01() { set<int> s1; //插入数据只有insert方式 s1.insert(10); s1.insert(40); s1.insert(30); s1.insert(20); s1.insert(30); //set容器特点: //所有元素插入时自动被排序 //set容器不允许插入重复的值 //遍历容器 printSet(s1); //拷贝构造 set<int> s2(s1); printSet(s2); //赋值 set<int> s3; s3 = s2; printSet(s3); } int main() { test01(); system("pause"); return 0; }
7.3、set大小和交换
功能描述:
-
统计set容器大小以及 交换set容器
#include <iostream> #include <set> using namespace std; /* size(); //返回容器中元素的数目 empty(); //判断容器是否为空 swap(st); //交换连个集合容器 没有resize():set容器不允许有重复的数,resize 默认填充值都是0,所以没有 */ //set容器 大小和交换 void printSet(set<int> &s) { for (set<int>::iterator it = s.begin(); it != s.end();it++) { cout << *it << " "; } cout << endl; } //大小 void test01() { set<int> s1; //插入数据 s1.insert(10); s1.insert(30); s1.insert(40); s1.insert(20); //打印容器 printSet(s1); if (s1.empty()) { cout << "s1 为空" << endl; } else { cout << "s1不为空" << endl; } cout << "s1的大小为:" << s1.size() << endl; } //交换 void test02() { set<int> s1; //插入数据 s1.insert(10); s1.insert(30); s1.insert(40); s1.insert(20); set<int> s2; //插入数据 s2.insert(100); s2.insert(300); s2.insert(400); s2.insert(200); cout << "交换前:" << endl; printSet(s1); printSet(s2); s1.swap(s2); cout << "交换后:" << endl; printSet(s1); printSet(s2); } int main() { //test01(); test02(); system("pause"); return 0; }
7.4、set插入和删除
#include <iostream> #include <set> using namespace std; /* insert(elem); //在容器中插入元素 clear(); //清除所有元素 erase(pos); //删除pos迭代器所指的元素,返回下一个元素的迭代器 erase(bfg,end);//删除区间[beg,end)的所有元素,返回下一个元素的迭代器 erase(elem); //删除容器中值为elem的元素 */ //set容器 插入和删除 void printSet(set<int> &s) { for (set<int>::iterator it = s.begin(); it != s.end();it++) { cout << *it << " "; } cout << endl; } void test01() { set<int> s1; //插入数据 s1.insert(30); s1.insert(10); s1.insert(40); s1.insert(20); //10 20 30 40 printSet(s1); //删除 传入迭代器 s1.erase(s1.begin()); //20 30 40 printSet(s1); //删除重载版本 传入元素 s1.erase(30); printSet(s1); //清空 提供区间的方式 //s1.erase(s1.begin(),s1.end()); s1.clear(); printSet(s1); } int main() { test01(); system("pause"); return 0; }
7.5、set查找和统计
#include <iostream> #include <set> using namespace std; /* find(key); // 查找key是否存在,返回该键的元素的迭代器;若不存在,返回set.end(); count(key); //统计key的元素个数 (对于set而言,是0和1) */ //set容器 查找和统计 void printSet(set<int> &s) { for (set<int>::iterator it = s.begin(); it != s.end();it++) { cout << *it << " "; } cout << endl; } void test01() { set<int> s1; //插入数据 s1.insert(30); s1.insert(10); s1.insert(40); s1.insert(20); //10 20 30 40 printSet(s1); //查找 set<int>::iterator pos = s1.find(30); if (pos != s1.end()) { cout << "找到元素" << *pos << endl; } else { cout << "未找到元素" << endl; } } //统计 void test02() { set<int> s1; //插入数据 s1.insert(30); s1.insert(10); s1.insert(40); s1.insert(20); s1.insert(20); //10 20 30 40 printSet(s1); //统计30的个数 int num = s1.count(20); //对set而言,统计的结果 要么是0 要么是1 cout << "num = " << num << endl; } int main() { test01(); test02(); system("pause"); return 0; }
7.6、set和multiset区别
#include <iostream> #include <set> using namespace std; //set容器 和multiset 容器 区别 void printSet(set<int> &s) { for (set<int>::iterator it = s.begin(); it != s.end();it++) { cout << *it << " "; } cout << endl; } void test01() { set<int> s1; //插入数据 //using _Pairib = pair<iterator, bool>; //set.insert有两个返回值,一个迭代器,一个bool ,主要关注bool pair<set<int>::iterator,bool> ret = s1.insert(30); if (ret.second) { cout << "第一次插入成功" << endl; } else { cout << "第一次插入失败" << endl; } ret = s1.insert(30); if (ret.second) { cout << "第二次插入成功" << endl; } else { cout << "第二次插入失败" << endl; } //只有第一次插入成功 printSet(s1); multiset<int> ms; //允许插入重复的值 //multiset.insert有一个返回值,迭代器 ms.insert(100); ms.insert(100); for (multiset<int>::iterator it = ms.begin(); it != ms.end(); it++) { cout << *it << " "; } cout << endl; } int main() { test01(); system("pause"); return 0; }
7.7、pair对组创建
功能描述:
成对出现的数据,利用对组可以返回两个数据
#include <iostream> #include <string> using namespace std; /* pair<type,type> p(value1,value2); pair<type,type> p = make_pair(value1,value2); */ //对组的创建 void test01() { //第一种方式 pair<string,int> p("Tom",20); cout << "姓名:" << p.first << " 年龄:" << p.second << endl; //第二种方式 pair<string, int>p2 = make_pair("Jerry",30); cout << "姓名:" << p2.first << " 年龄:" << p2.second << endl; } int main() { test01(); system("pause"); return 0; }
7.2、set容器排序
-
set容器默认排序规则为从小到大。
-
利用仿函数可以改变排序规则。
set存放在内置数据类型
#include <iostream> #include <set> using na数据类型mespace std; //set容器的排序 ,set存放在内置数据类型 //仿函数,本质是一个类型 class MyCompare { public: //第一个()重载符号,第二个()参数列表 bool operator()(int v1,int v2) { return v1 > v2; } }; void test01() { set<int> s1; s1.insert(10); s1.insert(40); s1.insert(20); s1.insert(30); for (set<int>::iterator it = s1.begin(); it != s1.end(); it++) { cout << *it << " "; } cout << endl; //改变排序规则为从大到小,需要在insert前改变 //利用仿函数指定 set<int,MyCompare> s2; s2.insert(10); s2.insert(40); s2.insert(20); s2.insert(30); //与要遍历的容器一致 set<int, MyCompare> for (set<int, MyCompare>::iterator it = s2.begin(); it != s2.end(); it++) { cout << *it << " "; } cout << endl; } int main() { test01(); system("pause"); return 0; }
set存放自定义数据类型
#include <iostream> #include <string> #include <set> using namespace std; //set容器的排序,存放自定义数据类型 class Person { public: Person(string name, int age) { this->m_Name = name; this->m_Age = age; } string m_Name; int m_Age; }; //仿函数,本质是类 class comparePerson { public: bool operator()(const Person &p1, const Person &p2) { //按照年龄 降序 return p1.m_Age > p2.m_Age; } }; void test01() { set<Person, comparePerson> s; //创建Person 对象 Person p1("刘备", 24); Person p2("关羽", 28); Person p3("张飞", 25); Person p4("赵云", 21); //默认排序规则是从小到大,但自定义数据类型,编译器不知按照什么排序 //通常自定义数据类型都会指定排序规则 set<Person, comparePerson> s.insert(p1); s.insert(p2); s.insert(p3); s.insert(p4); for (set<Person, comparePerson>::iterator it = s.begin(); it != s.end(); it++) { cout << (*it).m_Name << ":" << it->m_Age << endl; } } int main() { test01(); system("pause"); return 0; }