一 set/multiset容器基本概念
1.1 set容器基本概念
Set的特性是。所有元素都会根据元素的键值自动被排序。Set的元素不像map那样可以同时拥有实值和键值,set的元素即是键值又是实值。Set不允许两个元素有相同的键值。
我们可以通过set的迭代器改变set元素的值吗?不行,因为set元素值就是其键值,关系到set元素的排序规则。如果任意改变set元素值,会严重破坏set组织。换句话说,set的iterator是一种const_iterator.
set拥有和list某些相同的性质,当对容器中的元素进行插入操作或者删除操作的时候,操作之前所有的迭代器,在操作完成之后依然有效,被删除的那个元素的迭代器必然是一个例外。
1.2 multiset容器基本概念
multiset特性及用法和set完全相同,唯一的差别在于它允许键值重复。
multiset示例代码:
void num_1(multiset<int> &p) //打印类
{
for (multiset<int>::iterator a = p.begin(); a != p.end();a++)
{
cout << *a << " ";
}
cout << endl;
}
int main(void)
{
multiset<int> p;
p.insert(1);
p.insert(1);
p.insert(9);
p.insert(2);
num_1(p); //自动排列打印
set示例代码:
#include <iostream>
#include<set>
void num_1(set<int> &p) //打印函数
{
for (set<int>::iterator a = p.begin(); a != p.end();a++)
{
cout << *a << " ";
}
cout << endl;
}
int main(void)
{
set<int> set1;
set1.insert(19);
set1.insert(2);
set1.insert(13); //set1不可以有重复的
set1.insert(10);
set1.insert(90);
num_1(set1);
if(set1.empty())
{
cout << "set1容器为空" << endl;
}
else{
cout << "set1容器大小为: " << set1.size() << endl;
}
// set1.empty(19);
set<int>::iterator pos = set1.find(2); //find找,反回值是相应的迭代器
if(pos == set1.end())
{
cout << "找到了" << *pos << endl;
}
else{
cout << "没找到" << endl;
}
return 0;
}
set降序:
void num_1(multiset<int> &p)
{
for (multiset<int>::iterator a = p.begin(); a != p.end();a++)
{
cout << *a << " ";
}
cout << endl;
}
class myCom //伪函数
{
public:
bool operator()(const int v1,const int v2) const //重载()
{
return v1 > v2;
}
};
int main(void)
{
set<int,myCom> set1; //默认升序 底层认为myCon是一个类,所以函数就需要一个小括号
//要在插入之前设置好
set1.insert(19);
set1.insert(2);
set1.insert(13);
set1.insert(10);
set1.insert(90);
for(set<int,myCom>::iterator it = set1.begin();it != set1.end();it++)
{
cout << *it << endl;
}
multiset代码:
void num_1(multiset<int> &p)
{
for (multiset<int>::iterator a = p.begin(); a != p.end();a++)
{
cout << *a << " ";
}
cout << endl;
}tiset
int main(void)
{
multiset<int> p;
p.insert(1);
p.insert(1);
p.insert(9);
p.insert(2);
num_1(p);
二 set常用API
2.1 set构造函数
底层:
set<T> st;//set默认构造函数:
mulitset<T> mst; //multiset默认构造函数:
set(const set &st);//拷贝构造函数
示例代码:
void num_1(set<int> &p) //打印函数
{
for (set<int>::iterator a = p.begin(); a != p.end();a++)
{
cout << *a << endl;
}
cout << endl;
}
int main()
{
set<int> v; set默认构造函数:
v.insert(1);
v.insert(2);
v.insert(3);
set<int> v2(v); //拷贝构造函数
num_1(v2);
注意:这里拆入为什么不能使用 push_back()?
set容器是一个有序且不重复的容器,在C++中实现为红黑树。这意味着set容器中的元素是按照某种顺序排列的,并且不能有重复的元素。
而push_back是vector容器和deque容器中的成员函数,用于在容器的尾部插入元素。
由于set容器是有序的,对于每个元素的插入都需要按照一定的规则来保持有序,因此需要使用set容器中的insert函数来插入元素,而不是push_back函数。
2.2 set赋值操作
底层:
set& operator=(const set &st);//重载等号操作符
swap(st);//交换两个集合容器
示例代码:
void num_1(set<int> &p) //打印函数
{
for (set<int>::iterator a = p.begin(); a != p.end();a++)
{
cout << *a << endl;
}
cout << endl;
}
int main()
{
set<int> v; set默认构造函数:
v.insert(1);
v.insert(2);
v.insert(3);
set<int> v2;
v2 = v; // 重载等号操作符
num_1(v2);
v2.swap(v); //交换
2.3 set大小操作
底层:
size();//返回容器中元素的数目
empty();//判断容器是否为空
示例代码:
int main()
{
set<int> v; set默认构造函数:
v.insert(1);
v.insert(2);
v.insert(3);
cout << v.size() << endl; // 返回容器中元素的数目
int a = v.empty(); // 判断容器是否为空
if(a) //为空返回 0 , 不为空返回 1;
{
cout << "v为空" << endl;
}
else
{
cout << "v不为空" << endl;
}
2.4 set插入和删除操作
底层:
insert(elem);//在容器中插入元素。
clear();//清除所有元素
erase(pos);//删除pos迭代器所指的元素,返回下一个元素的迭代器。
erase(beg, end);//删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。
erase(elem);//删除容器中值为elem的元素。
示例代码:
void num_1(set<int> &p) //打印函数
{
for (set<int>::iterator a = p.begin(); a != p.end();a++)
{
cout << *a << endl;
}
cout << endl;
}
int main()
{
set<int> v; set默认构造函数:
v.insert(1);
v.insert(2); // 在容器中插入元素。
v.insert(3);
// v.clear(); //删除所有元素
v.erase(v.begin()); //删除迭代器指向的元素
num_1(v);
v.erase(v.begin(), v.end()); //删除两个迭代器之间的所有元素
v.erase(1); //删除数值是1 的元素
2.5 set查找操作
底层:
find(key);//查找键key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end();
count(key);//查找键key的元素个数
lower_bound(keyElem);//返回第一个key>=keyElem元素的迭代器。
upper_bound(keyElem);//返回第一个key>keyElem元素的迭代器。
equal_range(keyElem);//返回容器中key与keyElem相等的上下限的两个迭代器。
示例代码:
void num_1(set<int> &p) //打印函数
{
for (set<int>::iterator a = p.begin(); a != p.end();a++)
{
cout << *a << endl;
}
cout << endl;
}
int main()
{
set<int> v; set默认构造函数:
v.insert(1);
v.insert(2); // 在容器中插入元素。
v.insert(3);
v.insert(4);
v.insert(5);
set<int>::iterator a = v.find(2); // 查找键key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end();
cout << *a << endl; //这里注意,a为迭代器,不能直接打印
int b = v.count(1);
cout << b << endl; // 查找键key的元素个数
set<int>::iterator c = v.lower_bound(3); // 返回第一个key>=keyElem元素的迭代器。
cout << *c << endl;
set<int>::iterator d = v.upper_bound(2); // 返回第一个key>keyElem元素的迭代器。
cout << *d << endl;
2.5.1 equal_range(keyElem)使用
示例代码:
pair<set<int>::iterator, set<int>::iterator> res = v.equal_range(3);
if (res.first != v.end())
{
cout << "equal_range中的lower_bound值为:" << *res.first << endl;
}
else
{
cout << "没找到" << endl;
}
if (res.second != v.end()) //判断迭代器是否指出去
{
cout << "equal_range中的upper_bound值为:" << *res.second << endl;
}
else
{
cout << "没找到" << endl;
}
equal_range返回值为两个迭代器:
range.first
:指向第一个等于 的元素的迭代器。range.second
:指向第一个大于 的元素的迭代器。- 这里可以使用对组来处理pair。
三 对组(pair)
对组(pair)将一对值组合成一个值,这一对值可以具有不同的数据类型,两个值可以分别用pair的两个公有属性first和second访问。
类模板:template <class T1, class T2> struct pair.
如何创建对组?
//第一种方法创建一个对组
pair<string, int> pair1(string("name"), 20);
cout << pair1.first << endl; //访问pair第一个值
cout << pair1.second << endl;//访问pair第二个值
//第二种
pair<string, int> pair2 = make_pair("name", 30);
cout << pair2.first << endl;
cout << pair2.second << endl;
//pair=赋值
pair<string, int> pair3 = pair2;
cout << pair3.first << endl;
cout << pair3.second << endl;
对组的优点有以下几点:
- 对组可以同时存储不同类型的数据,比如上述代码中的 string 和 int 类型。
- 对组可以通过成员变量 first 和 second 访问其中的元素,不需要使用额外的数据结构或方法。
- 对组可以通过赋值操作符直接进行赋值,方便快捷。
- 对组可以使用 make_pair 函数来创建,简化了代码书写的过程。