(ACM) C++ STL 之vector常见用法

STL是简单效率不错的工具,尤其几种容器都蛮方便的,掌握好能发挥不错的威力。让你更多的时间去思考解题思路,而不是每次都要写奇奇怪怪的代码模拟简单的功能,让整体代码变的臃肿,想象一下不可能每次排序要自己写把。 总得来说看能使代码思路清晰,简洁。所以我们很有必须学习和掌握基本的STL使用方法。


这里先总结下vector常用的用法。

为了使用vector 首先:

#include <bits/stdc++.h> //很方便的头文件 
using namespace std; //做题的话建议写,方便嘛

定义的常用方式:

vector<int> v;
//定义一个空的动态数组,存储int类型元素
vector<int> v(5);
//定义一个初始大小为5的动态数组(默认初始值都为0),存储int类型元素
vector<int> v(5,1);
//定义一个初始大小为5的动态数组,赋值都为1,存储int类型元素

基本操作:

    v[i]; // 以下标方式访问元素,很方便.
    v.push_back(x); //往尾部插入元素x (常用)
    v.insert(it, x); //向迭代器it指向的位置插入x,原位置后移 (蛮方便的,速度也快)。
             //举例:v.insert(v.begin(),1); 比较神奇5w次这样的操作 大概0.5s,自己写的O(n)函数大概2.5s
    v.size();//返回表长,注意是unsigned类型,如果v.size()为1,减去2就是一个很大的正整数数,看情况转(int)v.size()
    v.begin(); // 返回指向首元素的迭代器 
    v.end();    // 返回指向尾元素下一个位置的迭代器.
    
    v.front(); //取首元素的值 
    v.back(); // 取尾元素的值
    
    v.empty(); //表为空返回真,否则返回假
    v.clear(); //清空表中所有元素
    v.pop_back(); // 删除表尾元素
    v.erase(it); //删除迭代器it指向的元素
    v.erase(st, ed); //删除迭代器st和ed指定的元素[st,ed) (左闭右开)
    v.reserve(x); //预分配空间大小为x.

用到vector自然少不了常用的排序sort,那么排序方法有如下几种:

(sort的第三个参数是一个函数指针或一个函数对象,不写就使用默认(自己定义的结构体要排序必须要写比较规则) )

一:默认或使用标准库函数

一个参数

    vector<int >v;
    sort(v.begin(), v.end()); //默认,从小到大
    sort(v.begin(), v.end(), greater<int>()); //从大到小,降序排列
    sort(v.begin(), v.end(), less<int>()); // 从小到大,升序排列

 两个参数(不想写结构体的话可以用pair<int,int>)

vector<pair<int,int> >v; //pair实质上是一个结构体,其主要的两个成员变量是first和second
    v.push_back(make_pair(3,4)); //用make_pair来构造我们需要的pair.
    v.push_back(make_pair(4,5));
    sort(v.begin(), v.end()); //默认,按第一个数升序排列,若相同则按第二个数升序。
    sort(v.begin(), v.end(), greater<pair<int,int> >()); //按第一个数降序排列,若相同按第二个数降序。
    sort(v.begin(), v.end(), less<pair<int,int> >()); // 同默认
    cout << v[0].first << " " << v[0].second; // 用v[i].first 和 v[i].second 取值

 多个参数(当然你想要花里胡哨也可以写 vector<pair<pair<int,int>,int> >v; … 但还是建议写结构体把。

二:  自定义比较函数(常用)

 一般形式:

vector<int> v; 
bool cmp(int a, int b) { // 比较函数
    return a > b; // 降序
    // return a < b; 升序
}

sort(v.begin(),v.end(), cmp);

 结构体的话类似:

#include <bits/stdc++.h>
using namespace std;
struct test {
    int x,y;
    test(int _x = 0, int _y = 0) : x(_x), y(_y) {}
};
vector<test> v;
bool cmp(test a, test b) {
    return a.x > b.x;
}
int main(void ) {
    v.push_back(test(1,2)); //写个构造函数pb时方便很多.
    v.push_back(test(3,4));
    sort(v.begin(), v.end(), cmp);
    cout << v[0].x << endl; // 3
    return 0;
}

三 :重载结构体或类的比较运算符

//情况一:在结构体内部重载
#include <bits/stdc++.h>
using namespace std;
struct test {
    int x, y;
    test(int _x = 0, int _y = 0) : x(_x), y(_y) {}
    friend bool operator < (test a, test b) {
        return a.x > b.x; //按x降序排序
    }
  /*或(也可以加上const &更规范,比如在第三个参数写less<test>()时,必须按标准格式写)
    bool operator < (const test &a)const {
        return x > a.x; //按x降序排序
    }
    */
};
vector<test> v;
int main(void ) {
    v.push_back(test(1,2)); //写个构造函数pb时方便很多.
    v.push_back(test(3,4)); //用的多了,手速狗可以 #define pb pusb_back
    sort(v.begin(), v.end()); //不用写第三个参数
    cout << v[0].x << endl; // 3
    return 0;
}
 
//情况二:在外部重载
#include <bits/stdc++.h>
using namespace std;
struct test {
    int x, y;
    test(int _x = 0, int _y = 0) : x(_x), y(_y) {}
};
bool operator < (test a,test b) { //写在外面就不要friend了,参数要写全,更规范就写const &
    return a.x > b.x; //按x降序排序
}
vector<test> v;
int main(void ) {
    v.push_back(test(1,2)); //写个构造函数pb时方便很多.
    v.push_back(test(3,4)); //用的多了,手速狗可以 #define pb pusb_back
    sort(v.begin(), v.end()); //不用写第三个参数
    cout << v[0].x << endl; // 3
    return 0;
}

 补充下重载pair,写在全局里无效,主要原因是不在一个namespace中,是先在同名字空间下里找,没找到才会外面找

#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
namespace std {
    bool operator < (const pair<int,int> &a, const pair<int,int> &b) {
        return a.first > b.first;
    }
    bool operator > (const pair<int,int> &a, const pair<int,int> &b) {
        return a.first < b.first;
    }
}
vector<pair<int,int> > v;
int main() {
    v.pb(mp(1, 2));
    v.pb(mp(3, 4));
    sort(v.begin(),v.end());
     cout << v[0].first << endl; // 3
    sort(v.begin(),v.end(), greater<pair<int,int> >());
    cout << v[0].first << endl; // 1
}

四 :使用仿函数

#include <bits/stdc++.h>
using namespace std;
struct test {
    int x, y;
    test(int _x = 0, int _y = 0) : x(_x), y(_y) {}
};
vector<test> v;
struct cmp {
    //const 这里编译没有约束,但是对于明确的不可变参加上更严谨,上面的我有的没写,可以比较。
    bool operator() (const test &a, const test &b) {
        return  a.x > b.x; // 按x降序
    }
};
int main(void ) {
    v.push_back(test(1,2)); //写个构造函数pb时方便很多.甚至可以
    v.push_back(test(3,4)); //用的多了,手速狗可以 #define pb pusb_back
    sort(v.begin(), v.end(), cmp()); //传入函数对象.
    cout << v[0].x << endl; // 3
    return 0;
}

五 其他常用

    swap(v[1], v[2]); //交换元素.
    reverse(v.begin(), v.end()); //反转1234 -> 4321
    
    *max_element(v.begin(), v.end()); //找表里最大的数
    *min_element(v.begin(), v.end()); //找表里最小的数
    
    lower_bound(v.begin(), v.end(), x) - v.begin(); //二分法找第一个 大于等于x的下标
    upper_bound(v.begin(), v.end(), x) - v.begin(); //二分法找第一个 大于x的下标
    
    v.erase(unique(v.begin(), v.end()), v.end());//去重,1220330770.结果是1203070。一般是排序、去重、离散化时用到.
    vector <pair<int,int> >E[maxn]; // 一种建图思路.E[i][j] i为源点,E[i][j].first为第j条边终点, .second为距离     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值