写在前面:
- set/multiset属于关联式容器,底层结构是用二叉树实现。
- set/multise容器当中的所有元素都会在插入时自动被排序。
- set不允许容器中有重复的元素
- multiset允许容器中有重复的元素
关联容器就是通过键(key)来读取和修改元素。不同于map关联容器,它只是单纯键的集合。
构造函数
set<T> st;
//默认构造函数:set(const set &st);
//拷贝构造函数
赋值操作
set& operator=(const set &st);
//重载等号操作符
方法
- s.begin() // 返回指向第一个元素的迭代器
- s.end() // 返回指向最后一个元素之后的迭代器,不是最后一个元素
- s.rbegin() // 返回指向集合中最后一个元素的反向迭代器
- s.rend() // 返回指向集合中第一个元素的反向迭代器
- s.count() // 返回某个值元素的个数
- s.size() // 集合中元素的数目
- s.empty() // 如果集合为空,返回true(真)
- s.swap() // 交换两个集合变量
- s.insert() // 在集合中插入元素
- s.clear() // 清除所有元素
- s.erase() // 删除集合中的元素
- s.find() // 返回一个指向被查找到元素的迭代器
- s.get_allocator() // 返回集合的分配器
- s.equal_range() // 返回集合中与给定值相等的上下限的两个迭代器
- s.lower_bound() // 返回指向大于(或等于)某值的第一个元素的迭代器
- s.key_comp() // 返回一个用于元素间值比较的函数
- s.max_size() // 返回集合能容纳的元素的最大限值
- s.upper_bound() // 返回大于某个值元素的迭代器
- s.value_comp() // 返回一个用于比较元素间的值的函数
大小和交换
size();
//返回容器中元素的数目empty();
//判断容器是否为空swap(st);
//交换两个集合容器
代码:
#include <set>
#include <iostream>
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;
for (int i = 0; i < 4; ++i) {
s1.insert(i);
}
if (s1.empty()){
cout << "s1为空" << endl;
} else {
cout << "s1不为空" << endl;
cout << "s1的大小为: " << s1.size() << endl;
}
}
//交换
void test02()
{
set<int> s1;
for (int i = 0; i < 4; ++i) {
s1.insert(i);
}
set<int> s2;
for (int i = 10; i < 4; i--) {
s2.insert(i);
}
cout << "交换前" << endl;
printSet(s1);
printSet(s2);
cout << endl;
cout << "交换后" << endl;
s1.swap(s2);
printSet(s1);
printSet(s2);
}
int main() {
//test01();
test02();
system("pause");
return 0;
}
插入删除
insert(elem);
//在容器中插入元素。clear();
//清除所有元素erase(pos);
//删除pos迭代器所指的元素,返回下一个元素的迭代器。erase(beg, end);
//删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。erase(elem);
//删除容器中值为elem的元素。
代码:
#include <set>
#include <iostream>
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;
//插入
for (int i = 0; i < 4; ++i) {
s1.insert(i);
}
printSet(s1);
//删除
s1.erase(s1.begin());
printSet(s1);
s1.erase(3);
printSet(s1);
//清空
//s1.erase(s1.begin(), s1.end());
s1.clear();
printSet(s1);
}
int main() {
test01();
system("pause");
return 0;
}
排序
set容器默认是从小到大排序,我们可以通过仿函数改变排序规则
代码:
#include <set>
#include <iostream>
using namespace std;
class MyCompare
{
public:
bool operator()(int v1, int v2) {
return v1 > v2;
}
};
int main()
{
set<int> s1;
for (int i = 0; i < 5; ++i) {
s1.insert(i);
}
//默认从小到大
for (set<int>::iterator it = s1.begin(); it != s1.end(); it++) {
cout << *it << " ";
}
cout << endl;
//指定排序规则
set<int,MyCompare> s2;
for (int i = 0; i < 4; ++i) {
s1.insert(i);
}
for (set<int, MyCompare>::iterator it = s2.begin(); it != s2.end(); it++) {
cout << *it << " ";
}
cout << endl;
return 0;
}
set容器也可以存放自定义数据类型
代码:
#include <set>
#include <string>
#include <iostream>
using namespace std;
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;
}
};
int main()
{
set<Person, comparePerson> s;
Person p1("张三", 22);
Person p2("李四", 20);
Person p3("王五", 19);
Person p4("赵六", 25);
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;
}
return 0;
}