简介:所有元素都会在插入时自动被排序
本质:set/multiset属于关联式容器 底层结构是用二叉树实现
set和multiset区别:
set不允许容器中有重复的元素
multiset允许容器中有重复的元素
注意⚠️:只要包含了set头文件就可以使用multiset
set
set(const set &st); //拷贝构造
set& operator=(const set &st); //重载等号操作符
#include
using namespace std;
#include
void printSet(const set&s){
for(set::const_iterator it = s.begin();it != s.end();it++){
cout << *it << " ";
}
cout <s1;
//插入数据 只有insert方法
s1.insert(10);
s1.insert(30);
s1.insert(20);
s1.insert(20);
s1.insert(40);
//set容器的特点:所有的元素插入时会被自动排序
//set容器插入重复数据无用 每个元素只能出现一次
printSet(s1);
sets2(s1); //拷贝构造
printSet(s2);
sets3;
s3 = s2; //等号赋值
printSet(s3);
}
int main() {
test01();
return 0;
}
输出结果:
10 20 30 40
10 20 30 40
10 20 30 40
size(); //返回容器中元素个数
empty(); //判断容器是否为空
swap(st); //交换两个集合容器
注意⚠️:set容器并没有resize()函数 假如我们用resize把原先的容器扩展变长 resize会以零来填充 而set容器是不允许插入重复的值 所以问题出现在了这里
#include
using namespace std;
#include
//set容器大小和交换
void printSet(const set&s){
for(set::const_iterator it = s.begin();it != s.end();it++){
cout << *it << " ";
}
cout <s1;
//插入数据 只有insert方法
s1.insert(10);
s1.insert(30);
s1.insert(20);
s1.insert(40);
//打印容器
printSet(s1);
//判断是否为空
if(s1.empty()){
cout << "s1为空" << endl;
}else{
cout << "s1不为空" << endl;
cout << "s1的元素个数为: " << s1.size() << endl;
}
sets2;
s2.insert(9);
s2.insert(99);
s2.insert(999);
cout << "交换前: " << endl;
printSet(s1);
printSet(s2);
s1.swap(s2);
cout << "交换后: " << endl;
printSet(s1);
printSet(s2);
}
int main() {
test01();
return 0;
}
输出结果:
10 20 30 40
s1不为空
s1的元素个数为: 4
交换前:
10 20 30 40
9 99 999
交换后:
9 99 999
10 20 30 40
insert(elem); //在容器中插入元素elem
clear(); //清除所有元素
erase(pos); //删除pos迭代器所指的元素 返回下个元素的迭代器
erase(beg, end); //删除区间内的所有元素 返回下一个元素的迭代器
erase(elem); //删除容器中值为elem的元素
#include
using namespace std;
#include
void printSet(const set&s){
for(set::const_iterator it = s.begin();it != s.end();it++){
cout << *it << " ";
}
cout <s1;
//插入数据 只有insert方法
s1.insert(30);
s1.insert(10);
s1.insert(20);
s1.insert(40);
s1.insert(15);
//遍历
printSet(s1);
//删除
s1.erase(s1.begin()); //删除自动排序后的第一个元素10
printSet(s1);
s1.erase(30); //删除重载版本
printSet(s1);
//区间删除
s1.erase(s1.begin(),s1.end()); //相当于清空了
//清空
s1.clear(); //和上一行代码效果一样
}
int main() {
test01();
return 0;
}
输出结果:
10 15 20 30 40
15 20 30 40
15 20 40
find(key); //查找key是否存在 存在则返回该键的迭代器 不存在则返回set.end();
count(key); //统计key的元素个数
#include
using namespace std;
#include
void printSet(const set&s){
for(set::const_iterator it = s.begin();it != s.end();it++){
cout << *it << " ";
}
cout <s1;
//插入数据 只有insert方法
s1.insert(30);
s1.insert(10);
s1.insert(20);
s1.insert(40);
s1.insert(30);
//遍历
printSet(s1);
//通过迭代器去接收find的返回值
set::iterator pos = s1.find(30);
if(pos != s1.end()){
cout << "找到元素" << *pos << endl;
}else{
cout << "未找到元素" << endl;
}
//统计元素30的个数
unsigned long num1 = s1.count(30);
cout << "30的个数为: " << num1 << endl;
//统计元素300
unsigned long num2 = s1.count(300);
cout << "300的个数为: " << num2 << endl;
//总结:对set而言 count统计的结果不是1就是0 因为set不允许出现重复数
}
int main() {
test01();
return 0;
}
输出结果:
10 20 30 40
找到元素30
30的个数为: 1
300的个数为: 0
1.set不可以插入重复的数据 而multiset可以
2.set插入数据的同时会返回插入结果 表示插入成功(等下会详细讲到)
3.multiset不会检测数据 因此可以插入重复数据
#include
using namespace std;
#include
void printSet(const set&s){
for(set::const_iterator it = s.begin();it != s.end();it++){
cout << *it << " ";
}
cout <s;
//插入这个数据的时候会返回一个对组
//pair
//第一个迭代器代表插入到哪里了 第二个bool表明是否插成功了
pair::iterator, bool> ret = s.insert(10);
//ret.second表明对组中的第二个数据bool
if(ret.second){
cout << "第一次插入成功" << endl;
}else{
cout << "第一次插入失败" << endl;
}
ret = s.insert(10); //第二次插入10
if(ret.second){
cout << "第二次插入成功" << endl;
}else{
cout << "第二次插入失败" << endl;
}
}
void test02(){
multisetms;
//multiset只会返回一个代迭器 没有bool来判断是否插入成功
//所以multiset是允许插入重复的数据的
ms.insert(10);
ms.insert(10);
//遍历multiset
for(multiset::iterator it = ms.begin();it != ms.end();it++){
cout << *it << " ";
}
cout << endl;
}
int main() {
test01();
test02();
return 0;
}
输出结果:
第一次插入成功
第二次插入失败
10 10
功能描述:成对出现的数据 利用对组可以返回两个数据
pair
pair
#include
using namespace std;
#include
void test01(){
//第一种方式
pairp1("张三",25);
cout << "姓名:" << p1.first << " 年龄:" << p1.second << endl;
//第二种方式
pairp2 = make_pair("李四", 40);
cout << "姓名:" << p2.first << " 年龄:" << p2.second << endl;
}
int main() {
test01();
return 0;
}
输出结果:
姓名:张三 年龄:25
姓名:李四 年龄:40
主要技术点:set容器默认排序从小到大 利用仿函数 可以改变排序规则
仿函数就是重载了()运算符
注意⚠️:已经insert完的数据是不能改变排序规则了 要想改变规则必须在插入前就通过仿函数改变排序规则
#include
using namespace std;
#include
class MyCompare{
public:
//重载()运算符
bool operator()(int v1, int v2){
//降序
return v1 > v2;
}
};
void printSet1(set &s){
for(set::iterator it = s.begin();it !=s.end();it++){
cout << *it << " ";
}
cout << endl;
}
void printSet2(set &s){
for(set::iterator it = s.begin();it !=s.end();it++){
cout << *it << " ";
}
cout << endl;
}
void test01(){
sets1;
//插入的时候自动从小到大排序
s1.insert(30);
s1.insert(10);
s1.insert(20);
s1.insert(15);
printSet1(s1);
//指定排序规则从大到小
//按照仿函数的排序规则
sets2;
s2.insert(30);
s2.insert(10);
s2.insert(20);
s2.insert(15);
printSet2(s2);
}
int main() {
test01();
return 0;
}
输出结果:
10 15 20 30
30 20 15 10
#include
using namespace std;
#include
class Person{
public:
Person(string name, int age){
this->name = name;
this->age = age;
}
string name;
int age;
};
class comparePerson{
public:
bool operator()(const Person &p1, const Person &p2){
//降序
return p1.age > p2.age;
}
};
void printSet1(set &s){
for(set::iterator it = s.begin();it !=s.end();it++){
cout << "姓名:"<< it->name << " 年龄:" << it->age << endl;
}
cout << endl;
}
void test01(){
//自定义的数据类型 都会指定排序规则
//不然系统不知道按照什么排序
sets;
Person p1("张三",18);
Person p2("李四",40);
Person p3("王五",28);
s.insert(p1);
s.insert(p2);
s.insert(p3);
printSet1(s);
}
int main() {
test01();
return 0;
}
输出结果:
姓名:李四 年龄:40
姓名:王五 年龄:28
姓名:张三 年龄:18