C++ stl vector

目录

 

1.定义

2.基本函数

2.1.vector 构造:

2.2.vector添加元素

2.3.vector删除元素

2.4.vector重要的迭代器

2.5.vector其他函数

3.vector使用实例

3.1.初始化vector中的元素

3.2.遍历vector中的元素

3.3.vector中的元素排序(这里只是简单介绍一些对stl的算法,详细了解可以查看algorithm)

3.4.ve.size(),ve.capacity(),ve.resize(),ve.reserve()


1.定义

向量(vector)是一个封装了动态数组的顺序容器,它可以存放各种类型的对象是c++中一个较为常见且比较重要的容器,在C++下使用vector我们需要引入#include<vector>头文件

2.基本函数

2.1.vector 构造:

  • std::vector<int>  ve:创建一个空的vector
  • std::vector<int>  ve {1,2,3}:创建一个有元素1,2,3的vector
  • std::vector<int>  ve(20):创建一个有20个元素0的vector
  • std::vector<int>  ve(20,2):创建一个有20个元素2的vector
  • std::vector<int>  ve1(ve):创建一个和ve相同的vector
  • std::vector<int> ve2(ve1.begin(),ve1.end()):创建一个有[ve.begin(),ve.end()]之间元素的vector

2.2.vector添加元素

  • 如果vector中所对下标已申请空间,我们可以直接赋值(当vector.capacity()包含该下标,我们就可以直接访问):ve[1]=2
  • 如果我们需要扩展vector的空间可以使用以下函数
  1. ve.push_back(x):在向量尾部添加一个元素x
  2. ve.insert(ve.begin()+1, 3, 4):在ve[1]前加3个元素‘4’
  3. ve.insert(ve.begin() + 1, ve.begin(), ve.end()):在ve[1]前按顺序加ve的所有元素
  4. ve.insert(ve.begin() + 1, {1,2,3}):在ve[1]前按顺序加入{1,2,3}

2.3.vector删除元素

  • ve.pop_back():删除ve中最后一个元素
  • ve.erase(ve.begin() + 1):删除ve[1]
  • ve.clear():删除ve所有元素

2.4.vector重要的迭代器

  • ve.begin():返回正向迭代器的第一个元素
  • ve.end():返回正向迭代器的最后一个元素的下一个位置
  • ve.rbegin():返回反向迭代器的第一个元素,即vector中的最后一个元素
  • ve.rend():返回反向迭代器的最后一个元素的下一个位置,即vector中的第一个元素的前一个位置
  • ve.front():返回vector开头一个元素的引用
  • ve.back():返回vector最末一个元素的引用

2.5.vector其他函数

  • ve.empty():判断ve是否为空
  • ve.size():返回当前向量中元素个数
  • ve.capacity():返回当前向量中申所能容纳的元素个数,乘以类型大小为该向量申请的空间大小

3.vector使用实例

3.1.初始化vector中的元素

  • 上面已经介绍了多种如何声明一个vector,如何在vector中插入一个新的元素,下面介绍使用itoa对vector中的元素初始化
#include <numeric>
#include<iostream>
#include<vector>
void main()
{
	std::vector<int> ve;
	ve.resize(10);
	std::iota(ve.begin(), ve.end(), 1);
	for (auto ll: ve)
	{
		std::cout << ll << std::endl;
	}
}

3.2.遍历vector中的元素

  • 我们可以直接使用下表遍历vector中的元素
#include<vector>
#include<iostream>
int main()
{
	std::vector<int> a(5);
	a[0]=3;
	a[1]=4;
	a[2]=5;
	a[3]=6;
	a[4]=7;
	for(int i=0;i<a.size();i++)
	{std::cout<<a[i]<<std::endl;}
	return 0;
}

  •  我们可以借助ve.begin(),ve.end()访问vector中的元素
#include<vector>
#include<iostream>
int main()
{
	std::vector<int> a(5);
	a[0]=3;
	a[1]=4;
	a[2]=5;
	a[3]=6;
	a[4]=7;
	for(auto i=a.begin();i!=a.end();i++)
	{std::cout<<*i<<std::endl;}
	return 0;
}

  • 还有一种方式可以遍历vector的元素 
#include<vector>
#include<iostream>
int main()
{
	std::vector<int> a(5);
	a[0]=3;
	a[1]=4;
	a[2]=5;
	a[3]=6;
	a[4]=7;
	for(auto i:a)
	{std::cout<<i<<std::endl;}
	return 0;
}
  • 我们还可以使用for_each对vector中的元素进行遍历 
#include<vector>
#include<algorithm>
#include<iostream>
void out(int x)
{
	std::cout << x << std::endl;
}
void main()
{
	std::vector<int> a(5);
	a[0] = 3;
	a[1] = 4;
	a[2] = 5;
	a[3] = 6;
	a[4] = 7;
	std::for_each(std::begin(a), std::end(a), out);
}

 

3.3.vector中的元素排序(这里只是简单介绍一些对stl的算法,详细了解可以查看algorithm)

  • 我们可以直接使用algorithm中的函数完成对vector中元素的排序(sort完成正序排序,reverse完成反向排序)
#include<iostream>
#include<algorithm>
#include<vector>
void main()
{
	std::vector<int> ve;
	ve.push_back(12);
	ve.push_back(6);
	ve.push_back(11);
	ve.push_back(7);
	ve.push_back(13);
	std::sort(ve.begin(),ve.end());
	for (auto ll : ve)
	{
		std::cout << ll << std::endl;
	}
	std::reverse(ve.begin(), ve.end());
	for (auto ll : ve)
	{
		std::cout << ll << std::endl;
	}
}
  •  但vector中元素类型并不总是基础类型,当vector中元素不是基础类型的时候,我们可能要按照我们的需求重载sort和reverse
#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
struct Unit
{
	std::string a;
	int size ;
};
bool compare(Unit a,Unit b)
{
	return a.size < b.size;
}
void main()
{
	std::vector<Unit> ve;
	ve.push_back({ "aaa", 3 });
	ve.push_back({ "aaaaaaa", 7 });
	ve.push_back({ "aa", 2 });
	ve.push_back({ "aaaaaa", 6 });
	ve.push_back({ "aaaa", 4 });
	std::sort(ve.begin(), ve.end(), compare);
	for (auto ll : ve)
	{
		std::cout << ll.a<<" "<<ll.size << std::endl;
	}
}
  •  我们还可以使用重载运算符的方式按照我们的需求重载sort和reverse
#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
struct Unit
{
	std::string a;
	int size ;
};
bool operator<(const Unit x, const Unit y)
{
	return x.size < y.size;
}
void main()
{
	std::vector<Unit> ve;
	ve.push_back({ "aaa", 3 });
	ve.push_back({ "aaaaaaa", 7 });
	ve.push_back({ "aa", 2 });
	ve.push_back({ "aaaaaa", 6 });
	ve.push_back({ "aaaa", 4 });
	std::sort(ve.begin(), ve.end()); 
	for (auto ll : ve)
	{
		std::cout << ll.a<<" "<<ll.size << std::endl;
	}
}
  • 我们也可以使用max_element和min_element查找vector中最大值,最小值的函数
#include<iostream>
#include<algorithm>
#include<vector>
void main()
{
	std::vector<int> ve1;
	ve1.push_back(1);
	ve1.push_back(2);
	ve1.push_back(3);
	ve1.push_back(4);
	ve1.push_back(5);
	auto max_count = std::max_element(std::begin(ve1), std::end(ve1));
	std::cout << *max_count << std::endl;
}
  • 同样我们也可以对max_element和min_element查找vector进行重载
#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
struct Unit
{
	std::string a;
	int size ;
};

bool compare(Unit a,Unit b)
{
	return a.size < b.size;
}
void main()
{
	std::vector<Unit> ve;
	ve.push_back({ "aaa", 3 });
	ve.push_back({ "aaaaaaa", 7 });
	ve.push_back({ "aa", 2 });
	ve.push_back({ "aaaaaa", 6 });
	ve.push_back({ "aaaa", 4 });
	std::sort(ve.begin(), ve.end(), compare); 
	auto max_count = std::max_element(std::begin(ve), std::end(ve), [](Unit pr1, Unit pr2){ return pr1.size < pr2.size; });
	std::cout << max_count->a<<" "<<max_count->size<< std::endl;
}

 3.4.使用shuffle对vector中的元素随机排序

  • 我们可以使用shuffle对vector中的元素随机排序,可以参见下面一个例子
#include<iostream>
#include<vector>
#include<algorithm>
#include <random> 
#include <chrono>
void main()
{
	std::vector<int> a;
	srand(time(NULL));
	a.push_back(11);
	a.push_back(14);
	a.push_back(19);
	a.push_back(13);
	a.push_back(17);
	unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
	std::shuffle(a.begin(), a.end(), std::default_random_engine(seed));
	for (auto ll : a)
	{
		std::cout << ll << " ";
	}
}

3.5.ve.size(),ve.capacity(),ve.resize(),ve.reserve()

根据上面的介绍ve.size()是当前向量中元素个数,而ve.capacity()实际上和该向量申请空间相关,所以ve.size()<=ve.capacity()。但在一个vector应该可以被访问到的是ve.size()中的元素,而在ve.size()和ve.capacity()之间的是未初始化的元素,这些元素是不可以被访问到的。在visual studio2013中ve.size()和ve.capacity()之间的元素不可以访问,而在linux下,使用g++或clang++变异,我们会发现ve.size()和ve.capacity()之间的元素会被初始化为一个常数,大家可以在不同变异环境下运行下面的程序验证这件事

#include<stdio.h>
#include<vector>
#include<iostream>
int main()
{
	std::vector<int> a(10);
	a.push_back(6);
	a.push_back(2);
	a.push_back(3);
	std::cout<<a.capacity()<<std::endl;
	std::cout<<a.size()<<std::endl;
	std::cout<<a[11]<<std::endl;
	for(int i=0;i<20;i++)
	{std::cout<<a[i]<<std::endl;}
	return 0;
}

那么ve.resize(),ve.reserve()和ve.size(),ve.capacity()有什么关系,因为ve.resize()可以更改ve.size()的值,ve.reserve()可以更改ve.capacity()的值。当ve.resize()>ve.capacity()的时候,vector将调用realloc申请新的空间(在visual studio2013下在原空间基础上再申请\left \lfloor \frac{ve.size()}{2} \right \rfloor大小的空间,在linux下在原空间基础上再申请ve.size()大小的空间,为什么要申请大于我们当时需要的re.size()的空间,是因为每一次申请新空间都要花费较多的时间),但是在linux中vector在调用realloc申请新空间的时候并没有将原空间的内容清除,所以在原先的空间中我们依旧可以找到vector的内容,我们可以运行下面的程序调试观察:

#include<vector>
#include<iostream>
int main()
{
	std::vector<int> a(10);
	a[8]=6;
	a[9]=7;
	long long s=(long)&a[8];
	long long s1=(long)&a[0];
	std::cout<<&a[8]<<std::endl;
	std::cout<<s<<std::endl;
	a.resize(100);
	int *aa=(int *)s;
	std::cout<<*aa<<std::endl;
	a[99]=2;
	a[98]=4;
	return 0;
}

还要注意clear()只是将vector.size设为0,但是vector申请的空间并没有释放,而且一些vector的元素还是可以访问到的,下面例子将说明这个问题。

#include<vector>
#include<iostream>
int main()
{
	std::vector<int> a(10);
	a[8]=6;
	a[9]=7;
	a.clear();
	std::cout<<a.size()<<std::endl;
	std::cout<<a.capacity()<<std::endl;
	std::cout<<a[8]<<std::endl;
	return 0;
}

(未完待续)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值