文章目录
- vector介绍
- vector使用
- 一、构造函数
- 二、迭代器
- 三、vector增删查改
- 关于STL中参数的分析(以push_back为例)
- sort算法和仿函数使用
vector介绍
vector就是顺序表的封装,是一个模板类,如上图所示。为方便vector里可以存任何数据类型,因此搞成了模板。
第一个参数是模板类型T,T可以是int,double,char等,也可以是其他class或者struct
第二个参数是一个空间配置器
,(STL极致追求效率,向内存池来申请空间而不是直接向堆)。这个参数是缺省,一般不用管它。
vector使用
一、构造函数
构造函数 | 接口说明 |
---|---|
vector() | 无参构造 |
vector(size_type n,const value_type& val = value_type() | 构造并初始化n个val |
vector(const vector& x) | 拷贝构造 |
vector(InputIterator first,InputIterator last) | 使用迭代器构造 |
1. 全缺省参数
vector<int> vi;
vector<double> vd; //调用全缺省构造
2. n个val构造
vector<int> vi(5,0); //用5个0构造
char ch = 'x';
vector<char> vc(100,ch); //用100个ch构造
3. 拷贝构造
vector<int> v1(5,10);
vector<int> v2(v1); //用已存在的v1构造
vector<int> v3(vector<int>(10,6)); //匿名对象构造
4. 迭代器区间构造
int arr[] = {1,2,3,4,5,6,7,8,9,10};
int len = sizeof(arr)/sizeof(int);
vector<int> v(arr,arr+len); //arr的[0,len)构造
二、迭代器
Iterator的使用 | 接口说明 |
---|---|
begin + end | 获取第一个数据位置的迭代器 / 获取最后一个位置迭代器 |
rbegin + rend | 获取最后一个位置迭代器 / 获取第一个位置迭代器 |
//1.普通迭代器
int arr[] = {1,2,3,4,5,6,7,8,9};
vector<int> v(arr,arr+sizeof(arr)/sizeof(int));
vector<int>::iterator it = v.begin(); //普通迭代器
vector<int>::cont_iterator c_it = v.begin(); //const迭代器
vector<int>::reverse_iterator r_it = v.rbegin();//reverse迭代器(反向)
vector<int>::const_reverse_iterator c_r_it = v.rbegin();//反向const迭代器
//使用方法都相同,以普通迭代器为例
while(it != v.end() )
{
cout << *it << " ";
++it;
}
//注意 如果是反向迭代器必须使用rbegin和rend
while(r_it != v.rend()){ /* ... */ }
三、vector增删查改
vector增删查改 | 接口说明 |
---|---|
push_back | 尾插 |
pop_back | 尾删 |
insert | 再position前插入val |
erase | 删除position位置的数据 |
swap | 交换两个vector的数据空间 |
operator[] | 像数组一样访问 |
find | STL算法(头文件:algorithm) |
vector<int> v;
//插入元素
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.push_back(5);
v.push_back(6);
v.push_back(7); //v: 1 2 3 4 5 6 7
//删除元素
v.pop_back();
v.pop_back(); // v: 1 2 3 4 5
// ↓ 三种遍历方式
//遍历1:利用opertor[]
for(size_t i = 0;i<v1.size();++i)
{
cout << v[i] <<" ";
}
cout << endl;
//遍历2:迭代器
vector<int>::iterator it = v.begin();
while (it != v.end())
{
cout << *it << " ";
++it;
}
cout << endl;
//遍历3:范围for
//利用范围for遍历
for (auto e : v)
{
cout << e << " ";
}
cout << endl;
/************************************/
/** insert和 earse **/
/************************************/
vector<int> v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
v1.push_back(5);
//找到3的位置,在3的位置插入30 -- find使用迭代器
#include<algorithm>
vector<int>::iterator position = find(v1.begin(),v1.end(),3);
//如果找不到返回end()
if (position != v1.end())
{
v1.insert(position,30);
}
//如果找不到就不用动
for (auto i : v1)
{
cout << i << " ";
}
cout << endl;
/* 删除 */
//找到4并删除
position = find(v1.begin(), v1.end(), 4);
//如果找到了就删除
if (position != v1.end())
{
v1.erase(position);
}
for (auto i : v1)
{
cout << i << " ";
}
cout << endl;
关于STL中参数的分析(以push_back为例)
push_back的参数是 const value_type& val
关键:1. 参数是引用 2. const。 为什么要这样设计?
- 使用引用:传递自定义类型的时候,自定义类型可能很大,所以用引用可以减少拷贝
- 使用const:传递匿名对象,或者直接传递参数返回值,必须要用const接收
//以string为例 那么参数类型对于的是 const string&
vector<string> v;
//1.最初是这样用:
string str = "hello"
v.push_back(str);
//2.上面太麻烦,改用匿名对象
v.push_back(string("hello")); //匿名对象具有常属性,const是必须
//3.隐式类型转换
v.push_back("hello");
sort算法和仿函数使用
sort算法:
// sort第三个参数是一个仿函数,其实是一个类模板
// 缺省值是less类型 -> 升序
// 降序:greater类型
// less和greater都在 头文件中
// 但是如果只包含algorightm头文件,只能用less 因为包含了算法 就包含了排序 就可以用(排序默认是less) 但是没有包含greater类型
#include<vector>
#include<algorithm>
#include<functional>
vector<int> v1;
v1.push_back(3);
v1.push_back(5);
v1.push_back(1);
v1.push_back(4);
v1.push_back(2);
v1.push_back(6);
sort(v1.begin(), v1.end());
for (auto i : v1)
{
cout << i << " ";
}
cout << endl;
//打印 1 2 3 4 5 6
//定义仿函数对象
less<int> ls;
greater<int> gt;
sort(v1.begin(), v1.end(), gt); //传递greater类型的仿函数-->降序
for (auto i : v1)
{
cout << i << " ";
}
cout << endl;
//输出: 6 5 4 3 2 1