文章目录
- 一、什么是vector?
- 二、容器特性
- 三、基本函数实现
- 1.构造函数
- 2.增加函数
- 3.删除函数
- 4.遍历函数
- 5.判断函数
- 6.大小函数
- 7.其他函数
- 8.常用方法
- 四、简单介绍
- 五、vector的基本操作
- 1.vector对象的定义和初始化
- (1)、创建确定个数的元素
- (2)、值初始化
- (3)、vector的操作
- a、vector对象的size
- b、向vector添加元素
- c、vector的下标操作
- d、下标操作不添加元素
- 六、实例
- 1.vector定义及初始化示例**
- 2.在容器最后移除和插入数据
- 3.clear()清除容器中所有数据
- 5.访问(直接数组访问&迭代器访问)
- 6.删除向量示例
- 7.二维数组两种定义方法(结果一样)
一、什么是vector?
vector类称作向量类,它实现了动态数组,用于元素数量变化的对象数组。像数组一样,vector类也用从0开始的下标表示元素的位置;但和数组不同的是,当vector对象创建后,数组的元素个数会随着vector对象元素个数的增大和缩小而自动变化
- 基本用法
//头文件
#include < vector>
二、容器特性
1.顺序序列
顺序容器中的元素按照严格的线性顺序排序。可以通过元素在序列中的位置访问对应的元素。
2.动态数组
支持对序列中的任意元素进行快速直接访问,甚至可以通过指针算述进行该操作。操供了在序列末尾相对快速地添加/删除元素的操作。
3.能够感知内存分配器的(Allocator-aware)
容器使用一个内存分配器对象来动态地处理它的存储需求。
三、基本函数实现
1.构造函数
vector():创建一个空vector
vector(int nSize):创建一个vector,元素个数为nSize
vector(int nSize,const t& t):创建一个vector,元素个数为nSize,且值均为t
vector(const vector&):复制构造函数
vector(begin,end):复制[begin,end)区间内另一个数组的元素到vector中
2.增加函数
void push_back(const T& x):向量尾部增加一个元素X
iterator insert(iterator it,const T& x):向量中迭代器指向元素前增加一个元素x
iterator insert(iterator it,int n,const T& x):向量中迭代器指向元素前增加n个相同的元素x
iterator insert(iterator it,const_iterator first,const_iterator last):向量中迭代器指向元素前插入另一个相同类型向量的[first,last)间的数据
3.删除函数
iterator erase(iterator it):删除向量中迭代器指向元素
iterator erase(iterator first,iterator last):删除向量中[first,last)中元素
void pop_back():删除向量中最后一个元素
void clear():清空向量中所有元素
4.遍历函数
reference at(int pos):返回pos位置元素的引用
reference front():返回首元素的引用
reference back():返回尾元素的引用
iterator begin():返回向量头指针,指向第一个元素
iterator end():返回向量尾指针,指向向量最后一个元素的下一个位置
reverse_iterator rbegin():反向迭代器,指向最后一个元素
reverse_iterator rend():反向迭代器,指向第一个元素之前的位置
5.判断函数
bool empty() const:判断向量是否为空,若为空,则向量中无元素
6.大小函数
int size() const:返回向量中元素的个数
int capacity() const:返回当前向量张红所能容纳的最大元素值
int max_size() const:返回最大可允许的vector元素数量值
7.其他函数
void swap(vector&):交换两个同类型向量的数据
void assign(int n,const T& x):设置向量中第n个元素的值为x
void assign(const_iterator first,const_iterator last):向量中[first,last)中元素设置成当前向量元素
8.常用方法
1.push_back 在数组的最后添加一个数据
2.pop_back 去掉数组的最后一个数据
3.at 得到编号位置的数据
4.begin 得到数组头的指针
5.end 得到数组的最后一个单元+1的指针
6.front 得到数组头的引用
7.back 得到数组的最后一个单元的引用
8.max_size 得到vector最大可以是多大
9.capacity 当前vector分配的大小
10.size 当前使用数据的大小
11.resize 改变当前使用数据的大小,如果它比当前使用的大,者填充默认值
12.reserve 改变当前vecotr所分配空间的大小
13.erase 删除指针指向的数据项
14.clear 清空当前的vector
15.rbegin 将vector反转后的开始指针返回(其实就是原来的end-1)
16.rend 将vector反转构的结束指针返回(其实就是原来的begin-1)
17.empty 判断vector是否为空
18.swap 与另一个vector交换数据
四、简单介绍
- Vector<类型>标识符
- Vector<类型>标识符(最大容量)
- Vector<类型>标识符(最大容量,初始所有值)
- Int i[5]={1,2,3,4,5}
Vector<类型>vi(I,i+2);//得到i索引值为3以后的值- Vector< vector >v; 二维向量//这里最外的<>要有空格。否则在比较旧的编译器下无法通过
五、vector的基本操作
1.vector对象的定义和初始化
vector类定义了好几种构造函数,用来定义和初始化vector对象。如下示出几种初始化vector对象的方式:
定义 | 解释 |
vectorv1 | vector保存类型为T的对象。默认构造函数v1为空 |
vectorv2(v1) | v2是v1的一个副本 |
vectorv3(n,i) | v3包含n个值为i的元素 |
vectorv4(n) | v4含有值初始化的元素的n个副本 |
(1)、创建确定个数的元素
若要创建非空的vector对象,必须给出初始化元素的值。当把一个vector对象复制到另一个vector对象时,新复制的vector中每一个元素都初始化为原vector中相应元素的副本。但这两个vector对象必须保存同一种元素类型:
vector<int>vecInt1;
vector<int>vecInt2(vecInt1);
vector<string>vecString(vecInt1);//错误
可以用元素个数和元素值对vector对象进行初始化。构造函数用元素个数来决定vector对象保存元素的个数,元素值指定每个元素的初始值:
vector<int>ivec4(10,-1);
vector<string>svec(10,"hi!");
关键概念:vector对象动态增长
vector对象(以及其他标准库容器对象)的重要属性就在于可以在运行时高效地添加元素。因为vector增长的效率高,在元素值已知的情况下,最好是动态地添加元素。
虽然可以对给定元素个数的vector对象预先分配内存,但更有效的方法是先初始化一个空vector对象,然后再动态地增加元素。
(2)、值初始化
如果没有给出元素的初始化式,那么标准库将提供一个值初始化的(valueinitialized)元素初始化式。这个由库生成的初始值用于初始化容器中的每个元素。而元素初始化式的值取决于存储在vector中元素的数据类型。
如果vector保存内置类型(如int类型)的元素,那么标准库将用0值创建元素初始化值
如果向量保存类类型(如string)的元素,标准库将用该类型的默认构造函数创建元素初始值。
(3)、vector的操作
操作 | 解释 |
empty() | 如果 v 为空,则返回 true, 否则返回 false |
v . size () | 返回 v 中元素的个数 |
v . push _ back ( t ) | 在 v 的末尾增加一个值为 t 的元素 |
v [ n ] | 返回 v 中位置为 n 的元素 |
v1 = v2 | 把 v1 的元素替换为 v2 中元素的副本 |
v1 == v2 | 如果 v1 与 v2 相等,则返回 true |
!=, <, <=, >, >= | 保持这些操作符惯有的含义 |
a、vector对象的size
empty和size操作类似于string类型的相关操作。成员函数size返回相应vector类定义的size_type的值。
使用size_type类型时,必须指出该类型是在哪里定义的。vector类型总是包括vector的元素类型:
vector<int>::size_type//ok
vector::size_type//error
b、向vector添加元素
push_back()操作接受一个元素值,并将它作为一个新的元素添加到vector对象的后面,也就是“插入(push)”到vector对象的“后面(back)”:
//read words from the standard input and store the elements in a vector
stringword;
vector<string>text;//emptyvector
while(cin>>word){
text.push_back(word);//appendwordtotext
}
该循环从标准输入读取一系列string对象,逐一追加到vector对象的后面。首先定义一个空的vector对象text。每循环一次就添加一个新元素到vector对象,并将从输入读取的word值赋予该元素。当循环结束时,text就包含了所有读入的元素。
c、vector的下标操作
vector中的对象是没有命名的,可以按vector中对象的位置来访问它们。通常使用下标操作符来获取元素。vector的下标操作类似于string类型的下标操作。
vector的下标操作符接受一个值,并返回vector中该对应位置的元素。vector元素的位置从0开始。下例使用for循环把vector中的每个元素值都重置为0:
//reset the elements in the vector to zero
for(vector<int>::size_type ix=0;ix!=ivec.size();++ix)
ivec[ix]=0;
和string类型的下标操作符一样,vector下标操作的结果为左值,因此可以像循环体中所做的那样实现写入。另外,和string对象的下标操作类似,这里用size_type类型作为vector下标的类型。
在上例中,即使ivec为空,for循环也会正确执行。ivec为空则调用size返回0,并且for中的测试比较ix和0。第一次循环时,由于ix本身就是0,则条件测试失败,for循环体一次也不执行。
d、下标操作不添加元素
初学C++的程序员可能会认为vector的下标操作可以添加元素,其实不然:
vector<int>ivec;//emptyvector
for(vector<int>::size_typeix=0;ix!=10;++ix)
ivec[ix]=ix;//disaster:ivec has no elements
上述程序试图在ivec中插入10个新元素,元素值依次为0到9的整数。但是,这里ivec是空的vector对象,而且下标只能用于获取已存在的元素。
这个循环的正确写法应该是:
for(vector<int>::size_typeix=0;ix!=10;++ix)
ivec.push_back(ix);//ok:adds new element with value ix
必须是已存在的元素才能用下标操作符进行索引。通过下标操作进行赋值时,不会添加任何元素。
警告:仅能对确知已存在的元素进行下标操作
对于下标操作符([]操作符)的使用有一点非常重要,就是仅能提取确实已存在的元素,例如:
vector<int>ivec;//empty vector
cout<<ivec[0];//Error: ivec has no elements!
vector<int>ivec2(10);//vector with 10 elements
cout<<ivec[10];//Error:ivec has elements 0...9
试图获取不存在的元素必然产生运行时错误。
六、实例
1.vector定义及初始化示例**
- 定义
#include<iostream>
#include<vector>
using namespace std;
class A
{
//定义一个空类
};
int main()
{
//定义一个vector,保存int型
vector<int> vecInt;
//定义一个vector,保存float型
vector<float> vecFloat;
//定义一个vector,保存自定义类型A
vector<A> vecA;
//定义一个vector,保存指向类A的指针
vector<A*> vecPointA;
return 0;
}
- 初始化
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<vector>
using namespace std;
int main()
{
//int型vector,包含3个元素
vector<int> vecIntA(3);
//int型vector,包含3个元素且每个元素都是9
vector<int> vecIntB(3, 9);
//复制vecIntB到vecIntC
vector<int> vecIntC(vecIntB);
int iArray[] = { 2,4,6 };
//创建vecIntD
vector<int> vecIntD(iArray, iArray + 3);
//打印vectorA,此处也可以用下面注释内的代码来输出vector中的数据
//for(int i=0;i<vecIntA.size();i++)
//{
// cout<<vecIntA[i]<<" ";
//}
cout << "vecIntA:" << endl;
for (vector<int>::iterator iter = vecIntA.begin(); iter != vecIntA.end(); iter++)
{
cout << *iter << " ";
}
cout << endl;
//打印vecIntB
cout << "VecIntB:" << endl;
for (vector<int>::iterator iter = vecIntB.begin(); iter != vecIntB.end(); iter++)
{
cout << *iter << " ";
}
cout << endl;
//打印vecIntC
cout << "VecIntB:" << endl;
for (vector<int>::iterator iter = vecIntC.begin(); iter != vecIntC.end(); iter++)
{
cout << *iter << " ";
}
cout << endl;
//打印vecIntD
cout << "vecIntD:" << endl;
for (vector<int>::iterator iter = vecIntD.begin(); iter != vecIntD.end(); iter++)
{
cout << *iter << " ";
}
cout << endl;
return 0;
}
打印结果:
2.在容器最后移除和插入数据
例:
#include <string.h>
#include <vector>
#include <iostream>
using namespace std;
int main()
{
///pop_back()&push_back(elem)实例在容器最后移除和插入数据
vector<int>v1;//创建一个向量存储容器 int
for (int i = 0; i < 10; i++) // push_back(elem)在数组最后添加数据
{
v1.push_back(i*i);
cout << v1[i] << ",";
}
for (int i = 0; i < 5; i++)
{
v1.pop_back();//去掉数组最后一个数据
}
cout << "\n";
for (int i = 0; i < v1.size(); i++) //打印容器中剩余的数据
//size()容器中实际数据个数
{
cout << v1[i] << ",";
}
cout << "\n";
return 0;
}
打印结果:
3.clear()清除容器中所有数据
例:
#include <string.h>
#include <vector>
#include <iostream>
using namespace std;
int main()
{
vector<int>v1;//创建一个向量存储容器 int
for (int i = 0; i < 10; i++) // push_back(elem)在数组最后添加数据
{
v1.push_back(i*i);
cout << v1[i] << ",";
}
v1.clear();//清除容器中所以数据
cout << v1.size() << endl;
return 0;
}
打印结果:
4.排序
例子:
#include <string.h>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
//排序
vector<int>v2;//创建一个向量存储容器 int
v2.push_back(3);
v2.push_back(1);
v2.push_back(2);
v2.push_back(5);
v2.push_back(4);
sort(v2.begin(), v2.end());//从小到大;注意:sort 需要头文件 #include<algorithm>
cout << "从小到大:";
for (int i = 0; i < v2.size(); i++)
{
cout << v2[i] << ",";
}
cout << "\n" ;
cout << "从大到小:";
reverse(v2.begin(), v2.end());//从大到小
for (int i = 0; i < v2.size(); i++)
{
cout << v2[i] << ",";
}
cout << "\n"<<endl;
return 0;
}
打印结果:
5.访问(直接数组访问&迭代器访问)
实例:
#include <string.h>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
//访问(直接数组访问&迭代器访问)
//顺序访问
vector<int>v3;
for (int i = 0; i < 10; i++)
{
v3.push_back(i);
}
cout << "直接利用数组:";
for (int i = 0; i < 10; i++)//方法一
{
cout << v3[i] << " ";
}
cout << endl;
//方法二,使用迭代器将容器中数据输出
cout << "利用迭代器:";
vector<int>::iterator iter;//声明一个迭代器,来访问vector容器,作用:遍历或者指向vector容器的元素
for (iter = v3.begin(); iter != v3.end(); iter++)
{
cout << *iter << " ";
}
cout << "\n"<<endl;
return 0;
}
打印结果:
6.删除向量示例
例子:
#include<iostream>
#include<vector>
using namespace std;
int main()
{
//int型vector,
vector<int> vecIntA;
//循环插入1 到10
for (int i = 1; i <= 10; i++)
{
vecIntA.push_back(i);
}
cout << "删除第5个元素后的向量vecIntA:" << endl;
vecIntA.erase(vecIntA.begin() + 4);
//打印vectorA
for (vector<int>::iterator iter = vecIntA.begin(); iter != vecIntA.end(); iter++)
{
cout << *iter << " ";
}
cout << endl;
//删除第2-5个元素
cout << "删除第2-5个元素后的vecIntA:" << endl;
vecIntA.erase(vecIntA.begin() + 1, vecIntA.begin() + 5);
//打印vectorA
for (vector<int>::iterator iter = vecIntA.begin(); iter != vecIntA.end(); iter++)
{
cout << *iter << " ";
}
cout << endl;
//删除最后一个元素
cout << "删除最后一个元素后的vecIntA:" << endl;
vecIntA.pop_back();
//打印vectorA
for (vector<int>::iterator iter = vecIntA.begin(); iter != vecIntA.end(); iter++)
{
cout << *iter<< " ";
}
cout << endl;
return 0;
}
打印结果:
7.二维数组两种定义方法(结果一样)
方法一:
#include <string.h>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
//方法一
int N = 9, M = 9;
vector<vector<int> > v4(N); //定义二维动态数组大小5行
for (int i = 0; i < v4.size(); i++)//动态二维数组为5行6列,值全为0
{
v4[i].resize(M);
}
for (int i = 0; i < v4.size(); i++)//输出二维动态数组
{
for (int j = 0; j < v4[i].size(); j++)
{
v4[i][j] = 1;
cout << v4[i][j] << " ";
}
cout << "\n";
}
cout << endl;
return 0;
}
方法二:
#include <string.h>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
//方法二
int N = 9, M = 9;
vector<vector<int> > v5(N, vector<int>(M)); //定义二维动态数组5行6列
for (int i = 0; i < v5.size(); i++)//输出二维动态数组
{
for (int j = 0; j < v5[i].size(); j++)
{
v5[i][j] =1;
cout << v5[i][j] << " ";
}
cout << "\n";
}
return 0;
}
打印结果: