vector就是数组,动态增长的顺序表。
它和string的区别是什么呢?
一个是管理任意类型的数组,一个是管理管理字符数组。
为了提高内存申请和释放的效率,它的内存都不是直接从计算机来的,它是从内存池来的。
学习vector的成本其实非常低,因为我们之前学习过string,并且vector其实就是一个顺序表。
因为之前讲过STL,所以可能有一些常用的会不讲,但是其实都是跟string一样的。
有个问题,怎样遍历vector呢?
和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);
第二个构造
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迭代器只读,不能写,具体就不演示了。
首先观察一下vector的扩容情况。
vs很喜欢1.5被扩容。
g++喜欢二倍扩容。
知道空间多少提前开好空间比较提高效率
resize在string用的不多,但是vector很喜欢用。
vector<int> v1;
v1.resize(10, 0);
vector的insert和string的insert还是有区别的,sting主要用的还是下标。但是vector用的都是迭代器。
string更多的是针对多个数据,vector更多的是针对单个数据。
vector是很不建议使用insert和erase的,学过顺序表的都非常清楚。
vector她自己没有提供查找,如果要查找用的还是std里的。
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的各种功能需求的。
接下来给大家看一道leetcode的一道题目
电话号码的字母组合
首先看到这道题,其实很容易看出它是用二叉树的深度遍历,只是它还要考虑其他的一些东西。