vector容器浅析

一、什么是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对象的方式:

定义解释
vectorv1vector保存类型为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;
}

打印结果:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值