C++STL的vector(超详解)

文章目录

前言

vector就是数组,动态增长的顺序表。

它和string的区别是什么呢?

一个是管理任意类型的数组,一个是管理管理字符数组。

为了提高内存申请和释放的效率,它的内存都不是直接从计算机来的,它是从内存池来的。

学习vector的成本其实非常低,因为我们之前学习过string,并且vector其实就是一个顺序表。

vector常用接口

因为之前讲过STL,所以可能有一些常用的会不讲,但是其实都是跟string一样的。

遍历方式

有个问题,怎样遍历vector呢?

和string一样,我们可以用下边+【】, 迭代器,范围for来访问。

cpp 复制代码
for (size_t i = 0; i < v.size(); ++i)
	{
		cout << v[i] << " ";
	}
	cout << endl;

	vector<int>::iterator it = v.begin();
	while (it != v.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;

	for (auto e : v)
	{
		cout << e << " ";
	}
	cout << endl;

这就是我们vector基本的一种玩法, 这三种除了可以读vector的数据,还可以写vector的数据。

拷贝构造

cpp 复制代码
vector<int> copy(v);

构造函数

第二个构造

cpp 复制代码
vector<int> v1(10, 1);

迭代器区间构造

cpp 复制代码
vector<int> v2(v1.begin(), v1.end());

注意,所有的迭代器区间都是左闭右开。

这个地方的迭代器可以传任意类型,它不止可以传vector,还可以传其他容器的迭代器,因为它是模板。

cpp 复制代码
string s1("hello world");
cout << s1 << " ";
cout << endl;
vector<char> v3(s1.begin() + 3, --s1.end());//很灵活
for (auto e : v3)
{
	cout << e << " ";
}
cout << endl;

迭代器

string用迭代器遍历很不舒服,为什么要用迭代器呢?

范围for是有缺陷的,只能正着遍历,也不能从中间某个位置开始遍历。

其实我们常见的容器,只有string和vector适用于【】,剩下的都要依靠迭代器。

反向迭代器

cpp 复制代码
//vector<int>::reverse_iterator rit = v.rbegin();
	auto rit = v.rbegin();
	while (rit != v.rend())
	{
		cout << *rit << " ";
		++rit;
	}
	cout << endl;

const迭代器

const迭代器只读,不能写,具体就不演示了。

reserve

首先观察一下vector的扩容情况。

vs很喜欢1.5被扩容。

g++喜欢二倍扩容。

知道空间多少提前开好空间比较提高效率

resize

resize在string用的不多,但是vector很喜欢用。

cpp 复制代码
vector<int> v1;
	v1.resize(10, 0);

insert 和erase

vector的insert和string的insert还是有区别的,sting主要用的还是下标。但是vector用的都是迭代器。

string更多的是针对多个数据,vector更多的是针对单个数据。

vector是很不建议使用insert和erase的,学过顺序表的都非常清楚。

find

vector她自己没有提供查找,如果要查找用的还是std里的。

vector为什么不自己提供一个find呢?

其实string自己设计一个find,更多是为了查找子字符串用的。vector没什么必要。

cpp 复制代码
vector<int>::iterator pos = find(v.begin(), v.end(), 2);
if (pos != v.end())
{
	v.insert(pos, 20);
}

最后一个问题,有了vector,可以用vector代替string吗?

不可以,这两者的区别还是蛮大的。

1.string有\0, vector没有,string更好的与C兼容。
2.vector比较数据没有什么意义
3.string使用+=很舒服,可以+=一个字符和多个字符,vector不能加多个字符,并且还要兼顾其他类型。
4.vector提供find,可以查找单个字符多个字符。

为什么要单独设计一个string?

因为string有很多它单独专用的需求,而vecotr是不能满足string的各种功能需求的。

17. 电话号码的字母组合

接下来给大家看一道leetcode的一道题目
电话号码的字母组合

首先看到这道题,其实很容易看出它是用二叉树的深度遍历,只是它还要考虑其他的一些东西。

既然要用深度遍历,那肯定自己得另外写一个函数,首先就是考虑一下要传什么参数,考虑不全也不要紧,等下需要得时候再加上。

接着我们就先把简单的事情做完,把深度遍历的框架大概写出来;

最后我们再考虑组合数据,并且把跟深度遍历结合起来。

最后这个范围for跟深度遍历结合起来真的是精妙绝伦。

相关推荐
JSU_曾是此间年少6 分钟前
数据结构——线性表与链表
数据结构·c++·算法
许野平18 分钟前
Rust: 利用 chrono 库实现日期和字符串互相转换
开发语言·后端·rust·字符串·转换·日期·chrono
也无晴也无风雨22 分钟前
在JS中, 0 == [0] 吗
开发语言·javascript
狂奔solar30 分钟前
yelp数据集上识别潜在的热门商家
开发语言·python
duration~33 分钟前
Maven随笔
java·maven
zmgst37 分钟前
canal1.1.7使用canal-adapter进行mysql同步数据
java·数据库·mysql
跃ZHD1 小时前
前后端分离,Jackson,Long精度丢失
java
此生只爱蛋1 小时前
【手撕排序2】快速排序
c语言·c++·算法·排序算法
blammmp1 小时前
Java:数据结构-枚举
java·开发语言·数据结构
何曾参静谧1 小时前
「C/C++」C/C++ 指针篇 之 指针运算
c语言·开发语言·c++