1、set基本概念 1.1、功能 所有元素都会在插入时自动被排序 1.2、本质: set/multiset属于关联式容器,底层结构是用二叉树实现。 1.3、set和multiset区别 set不允许容器中有重复的元素 multi
1、set基本概念
1.1、功能
- 所有元素都会在插入时自动被排序
1.2、本质:
- set/multiset属于关联式容器,底层结构是用二叉树实现。
1.3、set和multiset区别
- set不允许容器中有重复的元素
- multiset允许容器中有重复的元素
2、set构造和赋值
2.1、功能描述
创建set容器以及赋值
2.1、构造
- set<T> st; //默认构造函数:
- set(const set &st); //拷贝构造函数
2.3、赋值
- set& operator=(const set &st); //重载等号操作符
2.4、示例
//set容器的构造和赋值
void printSet(set<int> s) {
for (set<int>::iterator it = s.begin(); it != s.end();it++) {
cout << *it << " ";
}
cout << endl;
}
void test01() {
//1、默认构造
set<int> s;
//插入数据只能用insert
s.insert(10);
s.insert(60);
s.insert(40);
s.insert(50);
s.insert(30);
s.insert(20);
printSet(s);
//2、拷贝构造
set<int> s1(s);
printSet(s1);
//3、赋值
set<int> s2;
s2 = s1;
printSet(s2);
}
int main() {
test01();
system("pause");
return 0;
}
注意事项:
set容器插入数据时用insert();
3、set大小和交换
3.1、功能描述
- 统计set容器大小以及交换set容器
3.2、函数原型
- size(); //返回容器中元素的数目
- empty(); //判断容器是否为空
- swap(st); //交换两个集合容器
3.2、示例
//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> s;
s.insert(10);
s.insert(60);
s.insert(40);
printSet(s);
set<int> s1;
s1.insert(100);
s1.insert(600);
s1.insert(400);
printSet(s1);
//大小
//1、判断是否为空
if (s.empty()){
cout << "set容器为空" << endl;
}
else {
cout << "set容器不为空:" << endl;
//2、访问大小
cout << "大小为:" << s.size() << endl;
}
//交换
cout << "交换前:" << endl;
printSet(s);
printSet(s1);
s1.swap(s);
cout << "交换后:" << endl;
printSet(s);
printSet(s1);
}
int main() {
test01();
system("pause");
return 0;
}
4、set插入和删除
4.1、功能描述
- set容器进行插入数据和删除数据
4.2、函数原型
- insert(elem); //在容器中插入元素。
- clear(); //清除所有元素
- erase(pos); //删除pos迭代器所指的元素,返回下一个元素的迭代器。
- erase(beg, end); //删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。
- erase(elem); //删除容器中值为elem的元素。
4.3、示例
//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> s;
//1、插入
s.insert(10);
s.insert(60);
s.insert(40);
printSet(s);
//2.删除
s.erase(s.begin()); //删除指定位置
printSet(s);
s.erase(s.begin(),s.end()); //删除指定区间
printSet(s);
//3、清空 清空后打印一个换行
s.erase(s.begin(),s.end());
s.clear();
printSet(s);
}
int main() {
test01();
system("pause");
return 0;
}
5、set查找和统计
5.1、功能描述
- 对set容器进行查找数据以及统计数据
5.2、函数原型
- find(key); //查找key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end();
- count(key); //统计key的元素个数
5.3、示例
//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> s;
s.insert(10);
s.insert(60);
s.insert(40);
printSet(s);
//1、查找
set<int>::iterator it = s.find(10);
if (it != s.end()) {
cout << "查找到值:" << *it << endl;
}
else {
cout << "未找到!" << endl;
}
//2、统计
cout << "个数:" << s.count(10) << endl;
}
int main() {
test01();
system("pause");
return 0;
}
注意事项:
1、对于set而言,统计结果只有两个:0,1;
6、set和multiset区别
6.1、区别
- set不可以插入重复数据,而multiset可以
- set插入数据的同时会返回插入的bool结果,表示插入是否成功
- multiset不会检测数据,直接返回一个迭代器,因此可以插入重复数据
6.2、示例
//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> s;
pair<set<int>::iterator,bool> pai = s.insert(10);
if (pai.second) {
cout << "第一次插入10成功" << endl;
cout << *pai.first << endl;
}
else {
cout << "第一次插入10失败" << endl;
}
pai = s.insert(10);
if (pai.second) {
cout << "第二次插入10成功" << endl;
cout << *pai.first << endl;
}
else {
cout << "第二次插入10失败" << endl;
}
multiset<int> ms;
multiset<int>::iterator it = ms.insert(20);
cout <<"第一次插入:"<< * it << endl;
it = ms.insert(20);
cout << "第二次插入:" << *it << endl;
it = ms.insert(20);
cout << "第三次插入:" << *it << endl;
}
int main() {
test01();
system("pause");
return 0;
}
7、pair对组创建
7.1、功能描述
- 成对出现的数据,利用对组可以返回两个数据
7.2、两种创建方式
- pair<type, type> p ( value1, value2 );
- pair<type, type> p = make_pair( value1, value2 );
7.3、示例
//pair对组的创建
void test01() {
//第一种方式创建
pair<string, int> p("zhangsan",18);
cout << "姓名:" << p.first << "年龄:" << p.second << endl;
//第二种方式创建
pair<string,int>p1 = make_pair("lisi", 20);
cout << "姓名:" << p1.first << "年龄:" << p1.second << endl;
}
int main() {
test01();
}
8、set容器排序
问题描述:set容器默认排序规则为从小到大,如何改变排序规则?
8.1、主要技术点
- 利用仿函数,可以改变排序规则
8.2、示例
示例1: set存放内置数据类型
//排序规则,降序
class myCompare {
public:
bool operator()(int v1,int v2)const {
return v1 > v2;
}
};
void test() {
set<int> s;
//插入时,默认升序
s.insert(10);
s.insert(60);
s.insert(20);
s.insert(40);
s.insert(30);
s.insert(50);
//遍历
for (set<int>::iterator it = s.begin(); it != s.end();it++) {
cout << *it << " ";
}
cout << endl;
//改变排序规则——降序
set<int,myCompare> s1;
s1.insert(10);
s1.insert(60);
s1.insert(20);
s1.insert(40);
s1.insert(30);
s1.insert(50);
for (set<int,myCompare>::iterator it = s1.begin(); it != s1.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
int main() {
test();
}
总结:利用仿函数可以指定set容器的排序规则
示例2: set存放自定义数据类型
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,myCompare> 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>::iterator it = s.begin(); it != s.end();it++) {
cout << "姓名:" << it->m_name << "年龄:" << it->m_age << endl;
}
}
int main() {
test();
}
总结:
对于自定义数据类型,set必须指定排序规则才可以插入数据