STL之vector学习总结(C++)

概述

  1. STL提供3种顺序容器:vector、list、deque。vector和deque都是基于数组的,list实现链表数据结构。
  2. vector是STL最常用的容器之一。vector是动态数组,是可变长度的数组。
  3. vector对于末尾插入数据十分有效(增加新项目时相应增长),而在中间插入或删除的成本很高(插入或删除元素之后的整个vector部分都要移动)。
  4. vector和原始数组相同点:具有连续内存地址,因此vector类对象可以用重载下标运算符[ ]快速索引访问;下标不进行自动范围检查
  5. vector类与原始数组不同点:vector可以相互赋值(原始数组的数组名是常量指针,不能作为赋值目标)。vector类通过成员函数at提供范围检查的功能。
  6. vector容器最适用于达到性能最好的随机访问。
  7. 对于vector,同时插入多个元素比一次插入一个要快。
  8. 当vector的内存用尽时,vector自动分配更大的连续内存区,将原先的元素复制到新的内存区然后释放旧的内存区。
  9. 如果在已满的vector中添加元素,vector自动增加长度,有些版本可能自动将vector的长度翻倍。
  10. 虽然随机访问迭代器支持<,但是最好用!=和end()来测试容器末尾!
  11. vector支持随机访问迭代器,即vector可以使用下表内所有的迭代器操作。
    在这里插入图片描述

具体用法

0. 头文件

#include<vector>

1. 声明和初始化

//声明vector类的实例vec,存放int值,生成了一个长度为0的空vector,容量capacity为0
	vector<int>vec;
	
//声明一个int类型的二维向量vec
	vector<vector<int>>vec;

//声明一个int类型的一维向量vec,并将{1,2,3,4}赋值给vec
	vector<int>vec = {1,2,3,4};

//生成一个向量vec2,将vec复制给vec2
	vector<int>vec2 = vec; 
	或 vector<int>vec3(vec);

//生成一个向量vec,将数组a的a[0]到a[4]的内容复制给vec
	vector<int>vec(a,a+5);
	或 vector<int>vec4(&a[0], &a[4]);

//生成一个向量vec,将向量vec0从vec[0]到vec[2]的内容赋值给vec
	vector<int>vec(vec0.begin(),vec0.begin()+3);

//生成一个向量vec,将v大小设为10,且每个元素都为设置为0(默认)
	vector<int>vec6(10);

//生成一个向量vec,将大小设为10,且每个元素都为设置为5
	vector<int>vec7(10,5);

//将vec清空,然后添加2个元素,每个元素都赋值为10
	vec.assign(2, 10);

//将vec[2]赋值为10
	vec[2]=10;
或  vec.at(2) = 10;

//声明二维向量v1,将两个一维向量v2,v3赋值给v1
	vector<vector<int>>v1;
	vector<int>v2 = {1,7,8,9};
	vector<int>v3 = {2,10,45,1};
	v1.push_back(v2);
	v1.push_back(v3);


2. 常用函数(查询)

2.1 empty()

vec.empty(); //返回值bool类型,若vec为空,则返回true

2.2 size()

vec.size(); //返回值为int类型,vec当前存放的元素的个数

2.3 capacity()

vec.capacity(); //返回不增加内存时vec可以存放的元素个数,vec.capacity()>=vec.size()

2.4 front()

条件:vec不能为空,否则vec.front()结果是未定义!

vec.front(); //返回vec数组最前面的元素,即vec[0]

2.5 back()

条件:vec不能为空,否则vec.back()结果是未定义!

vec.back(); //返回vec数组最末尾的元素,即vec[vec.size()-1]

2.6 at() 和 下标运算符[ ]

用法与下标运算符相似。但是at()会检查是否越界,若越界会抛出out of range异常,而[ ]则不会检查

//访问第3个数
vec.at(2); 
vec[2];

//将第3个数赋值为10
vec.at(2)=10;
vec[2]=10;

2.7 迭代器

vector的迭代器通常实现为vector元素的指针。

//开始指针(正向)
vec.begin()

//结束指针(正向),指向vec最后一个元素的后一位
vec.end()

//开始指针(逆向)
vec.rbegin()

//结束指针(逆向),指向vec最后一个元素的后一位
vec.rend()

//常量开始指针(正向),不能通过该指针来修改所指内容
vec.cbegin()

//常量结束指针(正向),不能通过该指针来修改所指内容,指向vec最后一个元素的后一位
vec.cend()

2.8 输出

//迭代器,顺序访问
	for (vector<int>::iterator p = nums.begin(); p != nums.end(); p++)
		cout << *p << " ";

//输出迭代器,copy算法
	ostream_iterator<int> output(cout, " ");
	copy(vec.begin(),vec.end(),output);
	cout<<endl;

//迭代器,逆序访问
	for (vector<int>::reverse_iterator p = nums.rbegin(); p != nums.rend(); p++)
		cout << *p << " ";
		
//下标,顺序访问
	for (int i = 0; i < vec.size(); i++)
		cout << vec[i] << " ";
		
//下标,逆序访问
	for (int i = vec.size()-1; i >=0; i--)
		cout << vec[i] << " ";

//若是二维vector,注意传入参数是按值传递(不是&nums)因此在函数里对向量的修改不影响真正的向量的元素。顺序访问
void display_vector_two(vector<vector<int>> nums) {
	while (!nums.empty()) {
		for (vector<int>::iterator p = nums.front().begin(); p != nums.front().end(); p++)
			cout << *p << " ";
		cout << endl;
		nums.erase(nums.begin()); //每次输出一排就删除,指针指向下一排继续输出
	}
}

//还有一个基础的类似二维数组a[ ][ ]的输出方法,用下标运算符[ ]来输出,顺序访问
void display_vector_two(vector<vector<int>> nums) {
	for (int i = 0; i < nums.size(); i++) {
		for (int j = 0; j < nums[i].size(); j++) {
			cout << nums[i][j] << " ";
		}
		cout << endl;
	}
}


3. 常用函数(操作)

3.1 push_back()

//在末尾插入元素2
	vec.push_back(2);

3.2 pop_back()

//删除末尾元素
	vec.pop_back();

3.3 assign()

//将vec清空,然后添加2个元素,每个元素都赋值为10
	vec.assign(2, 10);
//将vec清空,然后将vec1[0]到vec1[3]复制给vec。相当于拷贝函数
	vec.assign(vec1.begin(),vec1.begin()+4)

2.4 insert()

//在第二个元素前插入10
	vec.insert(vec.begin()+1,10);

3.5 erase()

//删除vec[0]的元素
	vec.erase(vec.begin());
//删除从vec[0]到vec[4]的元素
	vec.erase(vec.begin(),vec.begin()+5);

3.6 swap()

//交换向量vec和向量vec1的元素
	vec.swap(vec1);

3.7 clear()

//清空向量
	vec.clear();

3.8 resize()

//重置向量的大小为10
	vec.resize(10);

4. 常用算法

4.0 头文件

#include<algorithm>

4.1 copy()

//将vec1[0]到vec1[3]的内容复制给vec
copy(vec1.begin(),vec1.begin()+4,vec);

4.2 reverse()

//元素翻转
reverse(vec.begin(), vec.end());

4.3 sort()

//排序默认(从小到大)
sort(vec.begin(), vec.end());

//排序(从大到小)
sort(vec.begin(), vec.end());
reverse(vec.begin(), vec.end());

//排序(从大到小),自己写一个判断条件给sort作为第三个参数
bool Comp(const int& a, const int& b) {
    return a > b;
}
sort(vec.begin(), vec.end(), Comp);

5.实际使用

5.1 二维数组

//若已知n行、m列:声明一个n行m列的二维数组v1[][]
vector<vector<int>> v1(n,vector<int>(m));

//若已知n行:声明一个n行0列的二维数组v2[][]
vector<vector<int>> v2(n); //此时列数为0
for (int i = 0; i < n; i++) { //得知列数后,修改列数为m
	v2[i].resize(m); 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值