C++STL的vector(超详解)

文章目录

  • 前言
  • vector常用接口
    • 遍历方式
    • 拷贝构造
    • 构造函数
    • 迭代器
    • reserve
    • resize
    • insert 和erase
    • find
  • 17. 电话号码的字母组合

前言

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

它和string的区别是什么呢?
一个是管理任意类型的数组,一个是管理管理字符数组。

C++STL的vector(超详解)_第1张图片
为了提高内存申请和释放的效率,它的内存都不是直接从计算机来的,它是从内存池来的。

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

vector常用接口

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

遍历方式

有个问题,怎样遍历vector呢?
C++STL的vector(超详解)_第2张图片
和string一样,我们可以用下边+【】, 迭代器,范围for来访问。

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的数据。

拷贝构造

vector<int> copy(v);

构造函数

C++STL的vector(超详解)_第3张图片

第二个构造

vector<int> v1(10, 1);

迭代器区间构造

vector<int> v2(v1.begin(), v1.end());

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

在这里插入图片描述
这个地方的迭代器可以传任意类型,它不止可以传vector,还可以传其他容器的迭代器,因为它是模板。

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适用于【】,剩下的都要依靠迭代器。

反向迭代器

//vector::reverse_iterator rit = v.rbegin();
	auto rit = v.rbegin();
	while (rit != v.rend())
	{
		cout << *rit << " ";
		++rit;
	}
	cout << endl;

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

reserve

首先观察一下vector的扩容情况。
C++STL的vector(超详解)_第4张图片
C++STL的vector(超详解)_第5张图片
vs很喜欢1.5被扩容。
g++喜欢二倍扩容。

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

resize

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

vector<int> v1;
	v1.resize(10, 0);

insert 和erase

vector的insert和string的insert还是有区别的,sting主要用的还是下标。但是vector用的都是迭代器。
string更多的是针对多个数据,vector更多的是针对单个数据。

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

find

vector她自己没有提供查找,如果要查找用的还是std里的。
C++STL的vector(超详解)_第6张图片

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

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的一道题目
电话号码的字母组合
C++STL的vector(超详解)_第7张图片
首先看到这道题,其实很容易看出它是用二叉树的深度遍历,只是它还要考虑其他的一些东西。

C++STL的vector(超详解)_第8张图片
既然要用深度遍历,那肯定自己得另外写一个函数,首先就是考虑一下要传什么参数,考虑不全也不要紧,等下需要得时候再加上。

C++STL的vector(超详解)_第9张图片

接着我们就先把简单的事情做完,把深度遍历的框架大概写出来;
C++STL的vector(超详解)_第10张图片

最后我们再考虑组合数据,并且把跟深度遍历结合起来。
C++STL的vector(超详解)_第11张图片
最后这个范围for跟深度遍历结合起来真的是精妙绝伦。

你可能感兴趣的:(c++,c++,java,开发语言)