set基本概念
简介:
所有元素都会在插入时自动被排序
本质:
set/multiset属于关联式容器,底层结构是用二叉树实现。
set和multiset区别:
set不允许容器中有重复的元素
multiset允许容器中有重复的元素
set构造和赋值
构造函数
set<T> st;
//默认构造函数:set(const set &st);
//拷贝构造函数
set 容器插入数据时用 insert
set 容器插入数据的数据会自动排序
赋值
set& operator=(const set &st);
//重载等号操作符
就是普通的等号赋值,没啥好说的…
代码
//set构造和赋值
#include<iostream>
#include<set>
using namespace std;
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(20);
s1.insert(30);
//遍历容器
//set容器特点:所有元素插入时自动被排序
//不允许插入重复值
printSet(s1);
//拷贝构造
set<int>s2(s1);
printSet(s2);
//赋值
set<int>s3;
s3 = s2;
printSet(s3);
}
int main()
{
test01();
return 0;
}
set大小和交换
大小
size();
//返回容器中元素的数目
empty();
//判断容器是否为空
set<int>s1;
s1.insert(10);
s1.insert(40);
s1.insert(20);
s1.insert(30);
printSet(s1);
//判断是否为空
if (s1.empty())
cout << "s1为空" << endl;
else
{
cout << "s1不为空" << endl;
cout << "s1的大小为:" << s1.size() << endl;
}
/*
10 20 30 40
s1不为空
s1的大小为:4
*/
交换
swap(st);
//交换两个集合容器
cout << "交换前:" << endl;
set<int>s1;
s1.insert(10);
s1.insert(40);
s1.insert(20);
s1.insert(30);
printSet(s1);
set<int>s2;
s2.insert(100);
s2.insert(400);
s2.insert(200);
s2.insert(300);
printSet(s2);
cout << "----------------" << endl;
s1.swap(s2);
cout << "交换后:" << endl;
printSet(s1);
printSet(s2);
/*
交换前:
10 20 30 40
100 200 300 400
----------------
交换后:
100 200 300 400
10 20 30 40
*/
代码
#include<iostream>
#include<set>
using namespace std;
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(20);
s1.insert(30);
printSet(s1);
//判断是否为空
if (s1.empty())
cout << "s1为空" << endl;
else
{
cout << "s1不为空" << endl;
cout << "s1的大小为:" << s1.size() << endl;
}
}
void test02()
{
cout << "交换前:" << endl;
set<int>s1;
s1.insert(10);
s1.insert(40);
s1.insert(20);
s1.insert(30);
printSet(s1);
set<int>s2;
s2.insert(100);
s2.insert(400);
s2.insert(200);
s2.insert(300);
printSet(s2);
cout << "----------------" << endl;
s1.swap(s2);
cout << "交换后:" << endl;
printSet(s1);
printSet(s2);
}
int main()
{
test01();
test02();
return 0;
}
set插入和删除
插入
insert(elem);
//在容器中插入元素。
删除
erase(pos);
//删除 pos 迭代器所指的元素,返回下一个元素的迭代器。erase(beg, end);
//删除区间[beg,end)
的所有元素 ,返回下一个元素的迭代器。erase(elem);
//删除容器中值为 elem 的元素clear();
//清除所有元素
代码
//set插入和删除
#include<iostream>
#include<set>
using namespace std;
void printSet(set<int>& s)
{
for (set<int>::iterator it = s.begin(); it != s.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
void test01()
{
set<int>s;
//插入数据
s.insert(10);
s.insert(30);
s.insert(20);
s.insert(40);
//遍历
printSet(s);
//10 20 30 40
//删除
s.erase(s.begin());
printSet(s);
//20 30 40
//删除重载版本
s.erase(30);
printSet(s);
//20 40
//清空
//s.erase(s.begin(), s.end());
s.clear();
printSet(s);
}
int main()
{
test01();
return 0;
}
set查找和统计
查找
find(key);
查找 key 是否存在, 若存在,返回该键的元素的迭代器;若不存在,返回set.end();
set<int>s1;
s1.insert(10);
s1.insert(30);
s1.insert(20);
s1.insert(40);
//查找
set<int>::iterator pos = s1.find(30);
if (pos != s1.end())
cout << "找到元素:" << *pos << endl;
else
cout << "未找到该元素" << endl;
统计
count(key);
统计 key 的元素个数(0/1)
set<int>s1;
s1.insert(10);
s1.insert(30);
s1.insert(20);
s1.insert(30);
s1.insert(40);
s1.insert(30);
s1.insert(30);
//统计30的个数
int num = s1.count(30);
//对于set而言,统计的个数只能是0或1,因为不允许插入相同的数
cout << "num=" << num << endl;
代码
//set查找和统计
#include<iostream>
#include<set>
using namespace std;
void test01()
{
set<int>s1;
s1.insert(10);
s1.insert(30);
s1.insert(20);
s1.insert(40);
//查找
set<int>::iterator pos = s1.find(30);
if (pos != s1.end())
cout << "找到元素:" << *pos << endl;
else
cout << "未找到该元素" << endl;
}
void test02()
{
//统计
set<int>s1;
s1.insert(10);
s1.insert(30);
s1.insert(20);
s1.insert(30);
s1.insert(40);
s1.insert(30);
s1.insert(30);
//统计30的个数
int num = s1.count(30);
//对于set而言,统计的个数只能是0或1,因为不允许插入相同的数
cout << "num=" << num << endl;
}
int main()
{
//test01();
test02();
return 0;
}
set和multiset的区别
set
不允许插入多个相同的数
pair<iterator, bool>
set 在进行 insert 插入的时候会返回对组的类型,其中 bool
用来判断是否插入成功
multiset
允许插入多个相同的数
代码
//set和multiset的区别
#include<iostream>
#include<set>
using namespace std;
void test01()
{
set<int>s1;
pair<set<int>::iterator, bool>ret = s1.insert(10);
if (ret.second)
//second为真表示插入成功
cout << "第一次插入成功" << endl;
else
cout << "第一次插入失败" << endl;
ret = s1.insert(10);
if (ret.second)
//second为真表示插入成功
cout << "第二次插入成功" << endl;
else
cout << "第二次插入失败" << endl;
multiset<int>s2;
//允许相同数据插入多次
s2.insert(10);
s2.insert(10);
for (multiset<int>::iterator it = s2.begin(); it != s2.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
int main()
{
test01();
return 0;
}
pair对组创建
创建方式
pair<type, type> p ( value1, value2 );
//第一种方式
pair<string, int>p1("Tom", 20);
//输出
cout << "姓名:" << p1.first << endl;
cout << "年龄:" << p1.second << endl;
pair<type, type> p = make_pair( value1, value2 );
//第二种方式
pair<string, int>p2 = make_pair("Jack", 30);
cout << "姓名:" << p2.first << endl;
cout << "年龄:" << p2.second << endl;
set排序
set 存放内置数据类型
- 利用仿函数修改 set 的默认排序规则
- 仿函数必须指定成 const,否则会报错,即
bool operator()(int v1, int v2)const
- 仿函数必须指定成 const,否则会报错,即
- 在创建 set 对象时,应该将类名作为第二个参数传递
set<int, MyCompare> myset;
<>
里面存放的应该是数据类型,而例子中的MyCompare
恰好是类
这种数据类型
//set排序
#include<iostream>
#include<set>
using namespace std;
class MyCompare
{
public:
//vs2022中 MyCompare中的operator()必须是 const 成员函数
bool operator()(int v1, int v2)const
{
//降序排列
return v1 > v2;
}
};
void test01()
{
//内置数据类型的排序
//指定排序规则为从大到小(指定规则必须在还没插入数据前才能生效)
set<int, MyCompare>s2;
s2.insert(10);
s2.insert(40);
s2.insert(20);
s2.insert(50);
s2.insert(30);
s2.insert(60);
for (set<int, MyCompare>::iterator it = s2.begin(); it != s2.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
int main()
{
test01();
return 0;
}
set 存放自定义数据类型
- 对于自定义类型,必须使用仿函数指定排序规则
bool operator()(const Person& p1, const Person& p2)const
- 注意要将仿函数指定成
const
类型,否则会报错
- 注意要将仿函数指定成
- 创建 set 对象时,要将仿函数所在的类的类名作为第二个参数传递
set<Person, ComparePerson>s;
#include<iostream>
#include<set>
using namespace std;
class Person
{
public:
string m_Name;
int m_Age;
Person(string name, int age) :m_Name(name), m_Age(age) {}
};
class ComparePerson
{
public:
bool operator()(const Person& p1, const Person& p2)const
{
//按照年龄降序
return p1.m_Age > p2.m_Age;
}
};
void test02()
{
set<Person, ComparePerson>s;
Person p1("刘备", 23);
Person p2("关羽", 27);
Person p3("张飞", 25);
Person p4("赵云", 21);
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 << "\t" << "年龄:" << it->m_Age << endl;
}
cout << endl;
}
int main()
{
test02();
return 0;
}