引言
这篇文章主要是记录下刷题的过程,复习C++的基础的同时防止后面又得再刷一遍,知识包括stl的基本使用,刷题过程时的模板,计算机相关的知识。可能会混一些计算机组成原理,编译原理相关的东西,默认读者已经学会基本数据结构,比如数组链表之类的概念,比较特殊的比如红黑树知道有这种结构。
一、stl
C++标准模板库。可以简单理解为一系列封装好的通用API,正常来说最多会看看源码,不搞操作系统底层的不用了解太透彻。
二、迭代器
可以理解为对容器中元素的一种抽象的指针,用来遍历容器,本质可以当作一个外部访问容器内部元素和容器内部实现的一种桥梁,可以让外部写遍历的时候只用调接口,不用关注具体的实现细节(比如sort,可以对map,vector等多个容器使用而不用担心链表该咋样咋样,数组该咋样咋样)。
三、vector
基础概念
动态数组,最常见的stl容器,首先基础概念,vector有两个重要的属性
- size:当前元素个数,有多少个元素
- capacity:当前容量,可以放多少个元素
核心思想是减少频繁的数据申请,当size==capacity时,就申请新的数据空间,大小一般是capacity的一定倍数(不同的实现倍数不一样,gcc一般是2倍,MSVC的某些版本是1.5倍,得看源码),为了减少频繁的空间申请,知道数组长度的话先用reserve()进行扩容是有效的办法。
常见用法
C++
// 常见构造
vector<T> arr;
vector<T> arr(n); //初始的容量设置为n,内部填充默认值
vector<T> arr(n,k); //初始的容量设置为n,内部填充k
vector<T> arr1(arr2); //拷贝构造
//改容量和大小
arr. reserve(n); //capacity变为n
arr.resize(n); //变大的话capacity和size都变为n,剩余的会填充默认值,也可以用自定义;
//变小的话capacity不变,size会变,移除多余元素
arr.shrink_to_fit() //不常用,尝试将capacity缩减到当前size大小,不保证成功
arr.empty(); //是否为空,只看size
// 元素增删改查,除了当数组用之外
arr.push_back(x); //末尾添加元素x
arr.emplace_back(x); // 同上,但是可以缉拿少一次临时对象的拷贝/移动
arr.pop_back(); //删除末位元素,调用析构但是不返回值
arr.clear(); //清空,capacity不变
arr.eraser(a); //擦除某个元素,返回指向被擦除元素的下一个元素的迭代器,可以加第二个参数表示擦除区间[a,b)
// 遍历,类似普通数组或者范围for循环,迭代器遍历很少见,没必要
for(int i=0;i<arr.size();i++)
arr[i]=i;
for(auto num:nums)
cout << num; //注意范围for循环的时候不要改里面的元素免得迭代器失效
一般来说,刷题的时候记住上面这些,另外说明下emplace_back和push_back的构造函数的区别如下:
- push_back(const T&)/push_back(T&&)
- emplace_back(Args&&... args)
也就是插入新元素的时候,push_back会创建一个临时对象,然后再添加到队尾,emplace_back会直接再队尾创建相关数据对象。不过如果是已经有一个对象只是想放到容器里或者int这种简单的数据类型,push_back性能上基本没差还更直观。
排序相关
stl有内部的sort算法,融合了快排,堆排等多种算法,依据数据的规模和特征会用不同的方法进行排序,比一般自己写的再大多数情况高效,记住一种写法即可
C++
sort(arr.begin(),arr.end(),fuc);
begin()和end()就是数组的迭代器,对这个范围内的数据进行排序,默认的是升序,可以用第三个fuc修改比较的优先级,一般的写法是这样
C++
sort(arr.begin(),arr.end(),
[ ](T a, T b){
// 给出优先级判断情况,a优先级高返回true ,否则返回false
// 优先级高的会排在前面
return a>b; //这种就是a更大优先级就更高,变为降序
}
);
a和b的类型可以是简单的int或者数组之类的东西,反正自己定义比较函数就可以。