1. 介绍
- set是一个集合容器,其中所包含的元素是唯一的, 集合中的元素按一定的顺序排列。
- 由于本身是有序的,因此不能指定元素的插入位置
- set是由变体的红黑树实现的。因此插入和删除操作比vector快
- set不支持直接存取元素,即不能通过 [] 操作符或at() 方法访问元素
- 不可以直接修改set和multiset中元素值,只能通过先删除在插入的方式修改
- 即set和multiset中元素类型都是const的
- set和multiset采用 < 操作符进行默认排序
- #include< set>
multiset与set区别:
- set中key唯一,只能出现一次;而multiset中key不唯一,可以重复出现
2. 额外类型说明
| 类型名 | 含义 |
|---|---|
| key_type | 表示set中关键字(key)的类型 |
| value_type | 与key_type相同 |
3. set/multiset构造函数
默认构造函数:
set<int> set_i;
set<string> set_s;
multiset<int> mulset_i;
set的拷贝构造和赋值:
set<int> setIntA;
setIntA.insert(3);
setIntA.insert(1);
set<int> setIntB(setIntA); // 拷贝构造
set<int> setIntC;
setIntC = setIntA; // 赋值构造,set重载了=操作符
4. set的排序方式与自定义排序
按升序方式排列:
set<int, less<int>> set1;
set1.insert(3);
set1.insert(2);
set1.insert(1); // 此时set1为1,2,3升序
按降序方式排列:
set<int, greater<int>> set2;
set2.insert(1);
set2.insert(2);
set2.insert(3); // 此时set2为3,2,1降序
// grater的具体实现如下
struct greater
{
bool operator() (const int& iLeft, const int& iRight) // 重载()操作符
{
return (iLeft>iRight); //如果是实现 less<int>的话,这边是写 return (iLeft<iRight);
}
}
上面的less 和greater 是stl中内置的函数对象,我们也可以根据需求自定义排序方式
自定义方式一:重载()运算符
// 学生类
class CStudent {
public:
CStudent(int id_n, string strName) {
m_id = id_n;
m_strName = strName;
}
int m_id; //学号
string m_strName; //姓名
};
// 定义比较对象,重载()运算符
struct StuFunctor {
bool operator() (const CStudent &stu1, const CStudent &stu2){
return (stu1.m_iID<stu2.m_iID);
}
};
// 调用
set<CStudent, StuFunctor> set_stu; // 定义set,传入比较对象
// 根据id升序排序
set_stu.insert(CStudent(3, "df"));
set_stu.insert(CStudent(1, "ewdf"));
自定义方式二:定义比较函数,传入函数指针
// 学生类
class CStudent {
public:
CStudent(int id_n, string strName) {
m_id = id_n;
m_strName = strName;
}
int m_id; //学号
string m_strName; //姓名
};
// 定义比较函数
bool compareId() (const CStudent &stu1, const CStudent &stu2){
return (stu1.m_iID<stu2.m_iID);
}
// 调用
// 定义set,传入比较函数的指针
// decltype指出自定义操作的类型,必须使用*来指定获取函数类型的指针
set<CStudent, decltype(compareId)*> set_stu;
// 根据id升序排序
set_stu.insert(CStudent(3, "df"));
set_stu.insert(CStudent(1, "ewdf"));
5. set插入与迭代器
| 操作 | 说明 |
|---|---|
| p.insert(v) p.emplace(args) | v是value_type类型;args用来构造一个元素。 只有当元素不存在时才插入; 函数返回一个pair<iterator, bool>,其中迭代器是指向具有指定关键字的元素,bool表示是否插入成功; 对于multiset,总会插入给定元素,并返回一个指向新元素的迭代器。 |
| p.insert(begin, end) p.insert(il) | begin和end是迭代器,表示一个p::value_type类型值的范围; il是值的花括号列表; 只插入关键字不在set中的元素; 返回类型为void; 对于multiset会插入范围内的所有元素,不检查key是否相等。 |
| p.insert(b, v) p.emplace(args) | b是迭代器,表示从哪里插入元素v; 返回一个迭代器,指向具有指定关键字的元素 。 |
set<int> setInt;
setInt.insert(3); setInt.insert(1);setInt.insert(5);setInt.insert(2);
for(set<int>::iterator it=setInt.begin(); it!=setInt.end(); ++it)
{
int iItem = *it;
cout << iItem; //或直接使用 cout << *it
}
//顺序输出 1 2 3 5
6. set删除
set.clear(); //清除所有元素
set.erase(pos); //删除 pos 迭代器所指的元素,返回下一个元素的迭代器。
set.erase(beg,end); //删除区间[beg,end)的所有元素,返回下一个元素的迭代器。
set.erase(elem); //删除容器中值为 elem 的元素。
7. set的查找操作
set.find(elem); //查找 elem 元素,返回指向 elem 元素的迭代器
set.count(elem); //返回容器中值为 elem 的元素个数。对 set 来说,要么是 0,要么是 1。对 multiset 来说,值可能大于 1
set.lower_bound(elem); //返回第一个>=elem 元素的迭代器
set.upper_bound(elem); // 返回第一个>elem 元素的迭代器
set.equal_range(elem); //返回一个迭代器pair,表示关键字等于elem的元素的范围。若k不存在,pair的两个成员均等于set.end()
本文介绍了C++中的set和multiset容器,它们是有序且不允许重复的集合。set由红黑树实现,提供快速的插入和删除操作,但不支持直接访问元素。multiset允许元素重复,其元素排序依据内置或自定义的比较函数。内容涵盖了set和multiset的基本操作,包括构造函数、排序方式、插入、删除和查找等。
3779

被折叠的 条评论
为什么被折叠?



