vector介绍
我对vector的认识就是C++提供的包装好的数组,即对象的集合,一般来说,刷题过程中普通数组都可以用vector来代替,毕竟vector有很对简单用法并且不用考虑长度问题。因为是基础用法部分,就不深究vector和数组的区别以及vector的特性了,直接进入使用吧
本vector用法说明由于只是针对leetcode刷题所写的常用用法,所以内容可能比较简略,只是vector的部分内容。
本文中的begin,end都是迭代器类型
声明
虽然leetcode上自动包含了所有头文件,但是如果自己编程使用vector要加上头文件
#include <vector>
再加上using namespace std;
或者
using std::vector;
创建,复制
vector<int> a; //创建一个空的vector
vector<int> a(n); //创建一个含有n个对象的vector,
//此时数据已缺省构造产生,比如现在的数组里全是0
vector<int> a(n, elem);//创建一个含有n个elem拷贝的vector
vector<int> a1(a2); //复制一个vector
vector<int> a1(begin, end); //将[begin,end)范围内的数据复制过来
关于最后一个用法有一个小坑可以注意一下,假设a2是一个含有4个int数据的vector,
如果你是这样用的:vector<int> a1(a2.begin(), a2.begin()+3),那么a1中实际有3个对象;
但如果你是这样用的:vector<int> a1(a2.begin(), a2.end()),那么a1中实际有4个对象。
这是因为a2.end()实际上指向的并不是vector最后一个对象,而是最后一个对象的下一个位置。
一般来说,leetcode刷题过程中都不用手动释放vector内存,所以我也就不写了
访问数据
a.begin() 返回指向首个对象的指针,也就是一般所说的迭代器
a.end() 返回指向最后一个对象的下一个位置的指针
a.begin()+1 返回指向首个对象的下一个对象的指针
a.end()-1 返回返回指向最后一个对象的指针
a.rbegin() 返回指向最后一个对象的指针,反向迭代器
a.rend() 返回指向首个对象的前一个位置的指针,反向迭代器
迭代器我个人觉得一开始不用深究,只需要知道他们是指向vector对象的指针即可
反向迭代器很容易搞混。。可以不用,如果用的话要记住,rend和end分别在vector的两头
a.front() 返回首个对象的数据,和*a.begin()是一样的
a.back() 返回最后一个对象的数据
a.at(i) 返回编号i位置处的对象数据,会检查数据是否存在
a[i] 返回编号i位置处的对象数据
这里建议大家尽量使用a.at(i)来返回数据,因为会检查数据是否存在
插入
a.push_back(i); //最简单的插入,直接向vector末尾加入一个数据
a.insert(pos,elem); //向pos迭代器指向的对象前插入一个对象,注意是对象前
a.insert(pos, n, elem); //向pos迭代器指向的对象前插入n个相同对象
a.insert(pos, begin, end); //向pos迭代器指向的对象前插入[begin,end)之间的对象
后三个函数都会返回新数据的位置
删除
a.clear(); //删除所有对象
a.pop_back(); //删除最后一个对象
a.erase(pos); //删除pos迭代器对应的对象
a.erase(begin, end); //删除[begin,end)之间的对象
后两个函数会返回被删除数据的下一个位置
注意,插入和删除都会导致指向插入或者删除的迭代器之后的位置的迭代器,指针,引用失效
比如
start = a.begin();
end = a.end();
a.insert(start, elem); //在begin前插入数据
a.erase(start, end); //会报错,因为此时end已经失效
上面的代码调整顺序以后就可以运行了:
start = a.begin();
end = a.end();
it = a.erase(start, end); //保存下删除之后的迭代器
a.insert(it, elem); //在it前插入数据
这里为了省事,没有写迭代器的具体类型
赋值
a[1] = 1; //令编号1的对象数据为1
a.assign(1, 1); //令a为{1}
a.assign(begin,end); //把另一个vector中[begin,end)中的数据赋值给a
要注意第一行和第二行结果是完全不同的,assign函数有点类似复制函数,是对整体的操作
其它常用函数
a.size() 返回vector中元素的个数
a.empty() 返回vector是否为空,空返回1,不为空返回0
a1.swap(a2); //交换a1,a2数据
swap(a1, a2); //交换a1,a2数据,同上
swap(a1[1], a1[2]); //交换a1的第2个数据和第3个数据
sort(begin, end); //对[begin,end)范围内的数据排序
注意,是没有a1[1].swap(a1[2])这种用法的。
关于sort:
你可以定义一个自己的比较条件来进行排序,比如:
class Solution {
public:
static bool cmp(vector<int> a, vector<int> b)
{
return a[0] < b[0];
}
int minMeetingRooms(vector<vector<int>>& intervals) {
sort(intervals.begin(), intervals.end(), cmp);
return 0;
}
};
注意,如果类中成员函数调用sort函数且使用自定义的cmp函数的话,此时cmp函数必须是static函数或者是全局的
非静态成员函数是依赖于具体对象的,而std::sort这类函数是全局的,因此无法在sort中调用非静态成员函数。
总结
本文主要介绍了vector的以下内容:
- 创建,复制
- 数据访问
- 插入,复制,删除
-
常用函数
- size()
- empty()
- swap()
- sort()
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。