3.8 set/multiset 容器
3.8.1 set基本概念
简介:
-
所有元素都会在插入时自动被排序
本质:
-
set/multiset 属于关联式容器,底层机构是用二叉树实现
set和multise区别:
-
set不允许容器中有重复的元素
-
multise 允许容器中有重复的元素
3.8.2 set构造和赋值
功能描述:创建set容器以及赋值
构造:
-
set<T> st; //默认构造
-
set(const set & st);
赋值:
-
set& operator = (const set & st); //重载等号操作符
示例:
#include <iostream> using namespace std; #include<string> #include<set> //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(50); s1.insert(30); s1.insert(20); s1.insert(60); s1.insert(40); //遍历容器 //set容器特点,所有元素插入时候自动被排序 //set容器不允许插入重复值 printSet(s1); //拷贝构造 set<int> s2(s1); printSet(s2); //赋值 set<int> s3; s3 = s2; printSet(s3); } int main() { test01(); system("pause"); return 0; }
效果如图:
总结:
-
set容器插入数据时用insert
-
set容器插入的数据会自动排序
3.8.3 set大小和交换
功能描述:
-
统计set容器大小以及交换set容器
函数原型:
-
size(); //返回容器中元素的数目
-
empty(); //判断容器是否为空
-
swap(st); //交换两个集合容器
示例:
#include <iostream> using namespace std; #include<string> #include<set> //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(50); s1.insert(30); s1.insert(40); s1.insert(5); //打印数据 printSet(s1); //判断是否为空 if (s1.empty()) { cout << "s1为空" << endl; } else { cout << "s1不为空 " << endl; cout << "s1的大小为" << s1.size() << endl; } //插入数据 set<int>s2; s2.insert(100); s2.insert(500); s2.insert(400); s2.insert(300); s2.insert(800); cout << "交换前:" << endl; printSet(s1); printSet(s2); s1.swap(s2); cout << "交换后" << endl; printSet(s1); printSet(s2); } int main() { test01(); system("pause"); return 0; }
效果图
总结:
-
统计大小 ---size
-
判断是否为空 ---empty
-
交换容器 ---swap
3.8.4 set插入和删除
功能描述:
-
set容器进行插入数据和删除数据
函数原型:
-
insert(elem); //在容器中插入元素
-
clear(); //清除所有元素
-
erase(pos); //删除pos迭代器所指的元素,返回下一个元素的迭代器
-
erase(beg,end); //删除区间[beg,end]的所有元素,返回下一个元素的迭代器
-
erase(elem); //删除容器中值为elem的元素
示例:
#include <iostream> using namespace std; #include<string> #include<set> //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(40); s1.insert(30); s1.insert(50); s1.insert(20); //打印数据 遍历 printSet(s1); //删除 s1.erase(s1.begin()); printSet(s1); //删除重载版本 s1.erase(30); printSet(s1); //清空 //s1.erase(s1.begin(), s1.end()); s1.clear(); printSet(s1); } int main() { test01(); system("pause"); return 0; }
效果图:
总结:
-
插入---insert
-
删除---erase
-
清空 ---clear
3.8.5 set查找和统计
功能描述:
-
对set容器进行查找数据以及统计数据
函数原型:
-
find(key); //查找key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end();
-
count(key); //统计key的元素个数
示例:
#include <iostream> using namespace std; #include<string> #include<set> //set 容器查找和统计 void test01() { set<int>s1; //插入数据 s1.insert(10); s1.insert(100); s1.insert(50); s1.insert(30); s1.insert(40); s1.insert(30); s1.insert(30); set<int>::iterator pos = s1.find(30); if (pos != s1.end()) { cout << "找到了元素" << *pos<<endl; } else { cout << "未找到元素" << endl; } //统计 //查找 //统计30的个数 int num=s1.count(30); //对于set而言,统计结果,num结果要么是0,要么是1 cout << "num=" << num << endl; } int main() { test01(); system("pause"); return 0; }
效果图:
总结:
-
查找 --find (返回的是迭代器)
-
统计 ---count(对于set,结果为0或1)
3.8.6 set和multise区别
学习目标:
-
掌握set和multiset的区别
区别:
-
set不可以插入重复数据,而multiset可以
-
set插入数据的同时会返回插入结果,表示插入是否成功
-
multiset不会检测数据,因此可以插入重复数据
示例:
#include <iostream> using namespace std; #include<string> #include<set> //set 容器和multiset容器的区别 void test01() { set<int> s1; pair<set<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<int>ms; //允许插入重复值 ms.insert(10); ms.insert(10); ms.insert(10); ms.insert(10); ms.insert(10); for (multiset<int>::iterator it = ms.begin();it!=ms.end();it++) { cout << *it << " "; } cout << endl; } int main() { test01(); system("pause"); return 0; }
效果图:
总结:
-
如果不允许插入重复数据可以利用set
-
如果需要插入重复数据利用multiset
3.8.7 pair对组创建
功能描述:
-
成对出现的数据,利用对组可以返回两个数据
两种创建方式:
-
pair<type,type> p(value1,value 2);
-
pair<type,type>p=make_pair(value1,value2);
示例:
#include <iostream> using namespace std; #include<string> //pair对组的创建 void test01() { //第一种方式 pair<string, int>p("tom", 20); cout << "姓名" << p.first << " 年龄: " << p.second << endl; //第二种方式 pair<string, int>p1 = make_pair("jerry", 10); cout << "姓名" << p1.first << " 年龄: " << p1.second << endl; } int main() { test01(); system("pause"); return 0; }
效果图:
总结:
两种方式都可以创建对组,记住一种即可
3.8.8 set容器排序
学习目标:
-
set容器默认排序规则从小到大,掌握如何改变排序规则
主要技术点
-
利用仿函数,可以改变排序规则
示例1:set存放内置数据类型
#include <iostream> using namespace std; #include<string> #include<set> //set容器的排序 class MyCompare { public: bool operator()(int v1, int v2) { return v1 > v2; } }; void test01() { set<int>s; //插入数据 s.insert(20); s.insert(40); s.insert(30); s.insert(50); s.insert(10); //遍历 for (set<int>::iterator it= s.begin();it!=s.end();it++) { cout << *it << " "; } cout << endl; //指定排序规则为从大到小 set<int,MyCompare>s2; //插入数据 s2.insert(20); s2.insert(40); s2.insert(30); s2.insert(50); s2.insert(10); //遍历 for (set<int,MyCompare>::iterator it = s2.begin(); it != s2.end(); it++) { cout << *it << " "; } cout << endl; } int main() { test01(); system("pause"); return 0; }
效果图:
总结: 利用仿函数可以指定set容器排序规则
示例2:set存放自定义的数据类型
#include <iostream> using namespace std; #include<string> #include<set> //set容器 排序,存放自定义数据类型 class Person { public: Person(string name, int age) { this->m_Age = age; this->m_Name = name; } 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() { //自定义数据类型 都会指定排序规则 //创建Person对象 Person p1("刘备",30); Person p2("关羽",28); Person p3("张飞",25); Person p4("赵云",25); Person p5("曹操",27); //插入数据 set<Person, comparePerson> s; s.insert(p1); s.insert(p2); s.insert(p3); s.insert(p4); s.insert(p5); 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; }
效果图:
总结:
对于自定义数据类型,set必须指定排序规则才可以插入数据