上一篇介绍了vector容器的基础功能,这一篇会有一些vector的基本功能
本篇内容需要包含头文件
#include <algorithm>
reverse:容器里的数据前后翻转
vector<int> vec{1, 2, 5, 9};
reverse(vec.begin(), vec.end());
// 这里的for循环是用一个int型变量num逐个遍历vec数组里面的所有值。
for (int num : vec) {
cout << num << ' ';
}
这里的vec.begin()和vec.end()就是告诉reverse我要从头翻转到尾。
sort:容器里的数据进行排序
vector<int> vec{1, 9, 5, 6, 2};
sort(vec.begin(), vec.end());
for (int num : vec) {
cout << num << ' ';
}
和reverse类似,也是传排序的起始和终点迭代器进去,默认是从小到大排序。
那如果现在我们需要从大到小排序怎么办?
诶,那我先sort然后再reverse一下不就好了吗。
有两种正儿八经的方法可以实现从大到小的排序,一种是使用反向迭代器。
vector除了支持正向迭代器vec.begin()和vec.end()从头遍历到尾,还支持一个反向迭代器vec.rbegin()和vec.rend()用来从尾遍历到头。
如果我们将rbegin和rend作为参数传入,因为默认从小排到大,那排序的逻辑就是:反向从小到大排序,也就是正向的从大到小排序了!
vector<int> vec{1, 9, 5, 6, 2};
sort(vec.rbegin(), vec.rend());
for (int num : vec) {
cout << num << ' ';
}
另一种方法就是自己传一个比较器进去,sort是可以传第三个参数作为比较器的:
sort(vec.begin(), vec.end(), greater<int>());
别管greater<int>()是啥玩意,你只需要知道把这玩意传进去之后就从大到小排了。
顺带一提,如果不传参数,默认传入的的就是less<int>()从小到大排。
这时候又会有同学说了,如果我这vector传的数据类型是不可直接比较的,能用sort来比较不?
当然也是可以的,只要第三个参数的比较器我们自己定义一个就行。
比如说我要在这里比较一个pair<int, float>数据类型,先简单介绍一下pair数据类型
(关于pair是什么玩意,你只需要知道这玩意里面存储的是一对数据就行,包含头文件如下)
#include <utility>
(pair<int, float>就代表了这一对数据里面存的分别是int和float。可以使用first和second分别访问和修改pair里面的两个值。使用例如下)
// 可以用pair<int, float> pr(3, 2.79)来构造,直接就赋值完了
pair<int, float> pr;
pr.first = 3;
pr.second = 2.79;
// 也可以直接使用pr = {3, 2.79}来赋值
假如我们希望的对比方式是根据所有pair里面的first值从小到大排序,second不参与排序的话,我们可以写出如下代码:
// 这个是自定义的比较器,用来告诉sort函数比较规则:只看first值,从小到大
// 不能使用<=,必须使用<
bool myCmp(pair<int, float> &a, pair<int, float> &b)
{
return a.first < b.first;
}
int main()
{
vector<pair<int, float>> vec(4);
vec[0] = {1, 2.79};
vec[1] = {5, 7.77};
vec[2] = {3, 114.514};
vec[3] = {2, 43.96};
sort(vec.begin(), vec.end(), myCmp);
for (pair<int, float> pr : vec) {
cout << pr.first << ' ' << pr.second << endl;
}
}
(上面函数传参数使用的是(&a, &b),这代表引用传递,可以节约时间,而且C++的特性为如果引用传递的参数被修改了,那么函数外面的变量也会跟着一起被修改。)
得出结果,只看first值从小到大排好序了
什么?你问为什么刚刚的greater<int>()调用的时候是右边有括号的,这里我自己定义的myCmp调用的时候没有括号?
真是喋喋不休的小妖精,有括号版本的也展示一遍
class myCmp{
public:
bool operator()(pair<int, float> &a, pair<int, float> &b)
{
return a.first < b.first;
}
};
int main()
{
vector<pair<int, float>> vec(4);
vec[0] = {1, 2.79};
vec[1] = {5, 7.77};
vec[2] = {3, 114.514};
vec[3] = {2, 43.96};
sort(vec.begin(), vec.end(), myCmp());
for (pair<int, float> pr : vec) {
cout << pr.first << ' ' << pr.second << endl;
}
}
至于为什么要这样写,别问,再问乱棍打死,用就是了
自定义排序的方法那叫一个多种多样:只看first排序啊;只看second排序啊;先看first,如果first一样就使用second排序啊;用first值和second值相加排序啊……总而言之多种多样,实现方法读者可以自行思考,在此不再赘述。
排序算法的其他知识
C++这里内置使用的排序算法是快速排序。
这里顺便提一句,虽然C++直接内置了快速排序,但自己还是得了解比较重要的排序方法的底层实现,面试可能会问到(建议得会快速排序和归并排序)。
如果不会的话寄几百度搜,难道还能指望我讲的比别人好不成。