2)vector容器内置的一些小功能:reverse和sort

上一篇介绍了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++直接内置了快速排序,但自己还是得了解比较重要的排序方法的底层实现,面试可能会问到(建议得会快速排序和归并排序)。

如果不会的话寄几百度搜,难道还能指望我讲的比别人好不成。

  • 9
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值