集合(Vector)
前言
正所谓集合,我们可以把它理解成动态数组,每一次向集合中添加元素相当于动态的开辟内存空间。
相比于数组来说,集合灵活了很多,大大增加空间的可控性
初始化
集合可以简单分为一维集合和二维集合
我们可以像数组一样分配预定义的大小
一维
vector<int> v(n); //定义一个n大小的集合
vector<int> v(3,2); //定义长度为3的集合,初始值设置为2
二维
int a = 3,b = 5;
vector<vector<int>> v(a,vector<int>(b)); //定义一个3 * 5大小的二维集合
T e s t Test Test
vector<int> v = {1,2,3,4,5};
函数
常用
begin(v); //指针指向头指针
end(v); //指针指向最后一个元素的后面一个元素
find(begin(v),end(v),元素值); //返回迭代器,通过*p的方式揭开迭代器中的值,不如set count
v.push_back(); //添加
v.pop_back(); //弹出
swap(v[],v[]); //顾名思义交换集合中两位
v.back(); //返回集合中末尾元素,一般用来去除逆序前导0
v.size(); //长度
v.resize(); //增删容器
v.resize(10); //多则扩展(多处来的空间值默认为0),少则删除
v.resize(10,2); //指定多出来的默认值
erase(迭代器); //往往搭配前三种方法使用
clear(); //清空
empty(); //判断是否为空
reverse(begin(v),end(v)); //反转
sort(begin(v),end(v)); //对集合排升序
insert(); //不咋用
迭代器的值往往都是通过 a u t o auto auto来进行接收
书写的时候我们可能会认为 b e g i n ( v ) , e n d ( v ) begin(v),end(v) begin(v),end(v)反复的书写很麻烦,可以使用宏预先定义
#define all(x) begin(x),end(x)
VC遍历
迭代器遍历(别用了,累西)
for (auto iter = v.begin(); iter != v.end(); iter++)
{
cout << (*iter) << endl;
}
C++11 新用法
for(auto it : v) {
cout << it << endl;
}
想修改 i t it it的值改成 & i t \&it &it,输入也可以写成一下形式
int n; cin >> n;
vector<int> v(n);
for(auto &it : v) cin >> it;
C++20还有 f o r ( a u t o [ k e y , v a l ] : v ) for(auto [key,val] : v) for(auto[key,val]:v) ,但是现在主流还是C++11
Sort排序
简单排升序
sort(begin(v),end(v)); //对集合排升序
自定义函数排序
bool cmp(int a,int b) {
return a > b;
}
sort(begin(v),end(v),cmp);
结构体内排序(不如自定义)
struct Area{
int l,r;
bool operator < (const Area &a) const {
return r < a.r; //排升序
}
}area[N];
Lambda捕获(非常的好用)
这里简单介绍一下,想深入了解可以去看一下lambda的新用法。。。
sort(begin(v),end(v),[&](int a,int b){
return a > b; //降序
});
Emplace_back和push_back区别
emplace_back和push_back都用于向vector中添加新元素,但它们之间有一些重要的区别。
- push_back接受一个已存在的对象,并将其拷贝到vector的末尾。
- emplace_back接受参数,并在vector的末尾构造一个新的对象,而不是拷贝已存在的对象。
因此,emplace_back通常比push_back更高效,因为它避免了拷贝或移动已存在的对象。
Insert(迭代器,元素值)
简单理解,向指定迭代器位置的前面插入元素
插入头结点前面
v.insert(begin(v),2);
插入末尾
v.insert(end(v),2); //因为end是末尾元素的后一个
插入N个值
v.insert(begin(v),2,3); //向开头插入三个2