Vector 容器类整理

Vector 容器类

一、Vector简介

Vector(向量)是一个能够存放任意类型的动态数组,能够增加和压缩数据。

二、Vector容器特性

1、顺序序列

顺序容器中的元素按照严格的线性顺序排列。可以通过元素在序列中的位置访问对应的元素,即通过下标访问。

2、动态数组

支持对序列中的任意元素进行快速直接查询,甚至可以通过指针算数进行该操作,提供了在序列末尾相对快速地添加/删除元素的操作。类似于栈一样,只能在最后进行添加删除操作,当我们不知道自己所需的数组大小时,可以用Vector以节约空间。vector容器的大小可以自动增长,需要在代码中包含头文件**#include <vector>**

三、基本函数及用法
vector<int> v; //不指定长度
vector<int> v(n); // 指定长度为n
vector<int> v{1,2,3}; //一维vector直接赋值
vector<vector<int> > v2{{1,2,3},{4,5,6}};  //二维vector直接赋值

v.pop_back();  //删除最后一个元素
v.push_back(elem); //在尾部加入一个元素
v.size();  //返回容器的大小,即当前使用数据的大小
v.capacity;   //返回容器当前能够容纳的元素数量,即当前vector分配的大小
v.max_size();   //  得到vector最大可以是多大
v.resize();   //  改变当前使用数据的大小,如果它比当前使用的大,者填充默认值
v.reserve();   //  改变当前vecotr所分配空间的大小

v.at();   //得到编号位置的数据
v.begin();   // 得到数组头的指针
v.end();   //  得到数组的最后一个元素+1的指针
v.front();   //  得到数组头的引用
v.back();   //  得到数组的最后一个单元的引用
v.erase();   //  删除指针指向的数据项
v.clear();   //  清空当前的vector
v.rbegin();   //  将vector反转后的开始指针返回(其实就是原来的end-1)
v.rend();   //  将vector反转构的结束指针返回(其实就是原来的begin-1)
v.empty();   //  判断vector是否为空
v.swap();   //  与另一个vector交换数据


sort(a.begin(),a.end()); 
//对a中的从a.begin()(包括它)到a.end()(不包括它)的元素进行从小到大排列
reverse(a.begin(),a.end()); 
//对a中的从a.begin()(包括它)到a.end()(不包括它)的元素倒置,但不排列,如a中元素为1,3,2,4,倒置后为4,2,3,1
copy(a.begin(),a.end(),b.begin()+1); 
//把a中的从a.begin()(包括它)到a.end()(不包括它)的元素复制到b中,从b.begin()+1的位置(包括它)开始复制,覆盖掉原有元素
find(a.begin(),a.end(),10); 
//在a中的从a.begin()(包括它)到a.end()(不包括它)的元素中查找10,若存在返回其在向量中的位置
四、应用举例

**对 v.size()和 v.capacity()的补充:*,例如以下程序,可以看出程序自动的进行了扩容。即如果添加了一个元素,导致超过当前容器的容景,容量会自动增加。

#include <vector>
#include <iostream>
#include <iterator>
#include <string>
using namespace std;

int main()
{
	vector<string> array;
	array.reserve(5);
    
	//append some elements
	array.push_back("one");
	array.push_back("two");
	array.push_back("three");
	array.push_back("four");
	array.push_back("!");
	copy(array.begin(), array.end(), ostream_iterator<string>(cout, " "));
    //用于获取一个元素,同时保存在缓冲器中,可以供Cout输出,   关联cout,设置分隔符
	cout << endl;

	cout << "max_size():" << array.max_size() << endl;
	cout << "size():" << array.size() << endl;
	cout << "capacity():" << array.capacity() << endl;

	cout << "----------------------------" << endl;

	//swap second and fourth element
	swap(array[1], array[3]);
	//insert element "always" before element "?"
	array.insert(find(array.begin(), array.end(), "!"), "five");
	//assign "!" to the last element
	array.back() = "six";
	copy(array.begin(), array.end(), ostream_iterator<string>(cout, " "));
	cout << endl;

	// return maximum possible length of sequence 
	//回容器的最大可以存储的元素个数,这是个极限,当容器扩展到这个最大值时就不能再自动增大
	cout << "max_size():" << array.max_size() << endl;
	// return length of sequence
	cout << "size():" << array.size() << endl;
	// return current length of allocated storage
	cout << "capacity():" << array.capacity() << endl;
	return 0;
}

输出结果如下:

one two three four !
max_size():461168601842738790
size():5
capacity():5
----------------------------
one four three two five six
max_size():461168601842738790
size():6
capacity():7

当vector容器大小超过capacity时,vector会重新配置内部的存储器,这样就会导致和vector元素相关的所有reference、pointers、iterator都会失效,另外内存的重新配置会很消耗时间。

例如对以下程序:

#include <vector>
#include <iostream>
#include <iterator>
#include <string>
using namespace std;

int main( )
{
	vector<string> m_vector;
	m_vector.reserve(5);//当前空间够大,不会发生重新配置,插入新元素后有可能会重新分配  

	m_vector.push_back("hello");
	m_vector.push_back("C++");
	m_vector.push_back("world");

	vector<string>::iterator it = m_vector.begin();
	cout << "change size before, the first elemt is :" << *it << endl;

	cout << "push_back one elems......" << endl;
	m_vector.push_back("one");
	cout << "push_back one elemt after, the first elemt is :" << *it << endl;

	cout << "push_back two elems......" << endl;
	m_vector.push_back("two");
	m_vector.push_back("Censh");//当前大小超过当前的容量,导致重新分配内存  
	//it = m_vector.begin(); //内存重新分配后,重新获取指针可以避免指针失效  
	cout << "push_back two elemts after, the first elemt:" << *it << endl;//指针失效导致程序奔溃,  
	return 0;
}

输出结果:

change size before, the first elemt is :hello
push_back one elems…
push_back one elemt after, the first elemt is :hello
push_back two elems…
push_back two elemts after, the first elemt:hello

而当屏蔽掉以上程序倒数第四行的 it = m_vector.begin(); 之后,程序会崩溃,这是因为在最后push_back的时候容器当前大小超过当前的容量,导致了重新分配内存,这样就会导致和vector元素相关的所有reference、pointers、iterator都会失效,而内存重新分配后,重新获取指针可以避免指针失效 ,所以应尽量避免内存重新配置,常有的方法有:

1、reverse()时保留适当空间 2、利用构造函数创建出足够的空间 ,如:vector<int> v(80);

以上的补充:迭代器,要访问顺序容器和关联容器中的元素,需要通过“迭代器(iterator)”进行。迭代器是一个变量,相当于容器和操纵容器的算法之间的中介。迭代器可以指向容器中的某个元素,通过迭代器就可以读写它指向的元素。从这一点上看,迭代器和指针类似。

常用的正向迭代器:容器类名:: iterator 迭代器名; 例如:

vector<int>::iterator my_iter;

使用举例:

vector<int>::iterator it;
for(it=vec.begin();it!=vec.end();it++)
    cout<<*it<<endl;

下面看看使用vector创建二维数组:

例如:vector <vector <int> > array(3); (需要注意> >之间的空格,据说有的编译器里面(即使c++11)会出错),但是在这里试验时没加空格并没有出错,

#include <string.h>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

constexpr auto N = 5;
constexpr auto M = 7;
int main()
{
	vector<vector<int>> m_vector(N); //定义二维动态数组大小为5行 ,在这里试验了一下> >之间没有空格,正常编译的
	for (int i = 0; i < m_vector.size(); i++)//动态二维数组为5行7列,值全为0 
	{
		m_vector[i].resize(M);
	}

	for (int i = 0; i < m_vector.size(); i++)//输出二维动态数组 
	{
		for (int j = 0; j < m_vector[i].size(); j++)
		{
			cout << m_vector[i][j] << " ";
		}
		cout << endl;
	}
	return 0;
}

另外一种方法创建二维数组:

#include <string.h>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

constexpr auto M = 5;
constexpr auto N = 7;
int main()
{
	vector<vector<int> > m_vector(M, vector<int>(N)); //定义二维动态数组5行7列 

	for (int i = 0; i < m_vector.size(); i++)//输出二维动态数组 
	{
		for (int j = 0; j < m_vector[i].size(); j++)
		{
			cout << m_vector[i][j] << " ";
		}
		cout << endl;
	}
	return 0;
}

以上两种方法输出结果一样

注意:下标的方式只能读取已经存在的元素而不能写入,写入一般用push_back,例如以下是错误的:

vector<int> a;
for(int i=0;i<10;i++)
    a[i]=i;   //错误, 

另外vector的内存释放可以参考:https://blog.youkuaiyun.com/msdnwolaile/article/details/52708144

本文参考:

https://www.cnblogs.com/jinxiang1224/p/8468420.html

https://www.runoob.com/w3cnote/cpp-vector-container-analysis.html

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值