大家好,今天我们来讲讲与string相似的向量类型。之所以说他们是相似的原因是他们其中的数据类型有些效果都是一样的。当然大家不能说,既然是差不多的干嘛还有一个这个啊。不如直接用string就可以了。当然世界名言存在即合理。既然我们都能想到的东西,那些创始人大佬肯定也能想到这些。我自己认为的话:vector 是一个类模板,编译器根据模板创建类或函vector<string> 就是根据模板创建了若干 string 对象,而 string 本身可以包含字符串,字符串可以视为若干个字符,即,vector<string> 可以视为一个a [ ][ ] 数组。可以使用输出数组的方式来输出vector<string> 对象内的内容。但这些都不是我们这篇博客的主题。我们今天主要是想与大家分享一下,如何使用,好的吧。所以咧接下来我们来看看vector的一些用法。
vector的定义
在我们上面的博客中我们先写string的定义构造的,那么我们这里也先写vector的定义够造。但大家都知道定义构造我们都是有模板的,编译器会根据我们的参数不同来构造不同的数据存储空间。那么我们先看看vector中的几个关键的定义模板: 大家看到上面的这个图片是不是觉得好熟悉啊,和string的有点像呀。这就是我们在序言中讲过的。string与vector是有点相似的。那么我们接下来看看这些都是怎么写的吧。
vector<int> first; // empty vector of ints vector<int> second(4, 100); // four ints with value 100 vector<int> third(second.begin(), second.end()); // iterating through second vector<int> fourth(third); // a copy of third
这里大家不用太纠结,大概知道如何使用和作用就行了。如果大家对我这里的理解不是太熟悉的话我会在博客末尾的地方将我们的vector的官网链接给大家。大家可以在用的时候,点那个链接找就可以了。
vector iterator 的使用
大家可能看到这个小标题有点陌生但其实我们在string的时候就已经见过,并且使用过了,就是我们前面说过的迭代器。那么不知道大家对这个名词还有印象吗?如果在通透一点就是,我们前面将的begin和end。这个就叫迭代器。大家记住了,别忘了。后面要是有人说这个名词的话,大家不要二丈和尚摸不着头脑哈。大家也先先看看图片:
我们还知道吧。我们普通的begin和end就是我们正常头尾。然后加个r就是相反的
OK,当我们知道了vector的迭代器的作用,那么我们接下里就是我们写过代码的实现实例了。
void PrintVector(const vector<int>& v){// const对象使用const迭代器进行遍历打印vector<int>::const_iterator it = v.begin();while (it != v.end()){cout << *it << " ";++it;}cout << endl;}
大家可以结合我上一篇博客string一起来看看。
vector 空间增长问题
接下来就是我们的数据空间相关的几个重要的关键词吧。我觉得这样讲也好理解。对于数据空间的关键词中我相信大家应该对size还有很深的影响吧。毕竟我们在c的时候想要获得数组的个数还是要写一串的哦。在c++的时候就只需要写这么几个就可以了。虽然我们开始是在string中学习的size。但是我们在前面也说过了。我们的vector与我们的string是有相似之处的。所以我们这里vector也是有size的。还有一些,大家看看下面的图片:
这个大家要竖着看,别横着看哈。然后咧示例的话,大家看看下面的代码示例,应该也就了解的差不多了。
a.size(); //返回a中元素的个数;a.capacity(); //返回a在内存中总共可以容纳的元素个数a.resize(10); //将a的现有元素个数调至10个,多则删,少则补,其值随机a.resize(10,2); //将a的现有元素个数调至10个,多则删,少则补,其值为2a.reserve(100); //将a的容量(capacity)扩充至100,也就是说现在测试a.capacity();的时候返回值是100.这种操作只有在需要给a添加大量数据的时候才显得有意义,因为这将避免内存多次容量扩充操作(当a的容量不足时电脑会自动扩容,当然这必然降低性能)
这里还有一个点就是capacity的代码在vs和g++下分别运行会发现,vs下capacity是按1.5倍增长的,g++是按2倍增长的。这个问题经常会考察,不要固化的认为,vector增容都是2倍,具体增长多少是根据具体的需求定义的。就是说我们的vector在外面使用的时候会有一个大致的内存空间,然后我们使用的时候如果超了的话,那么就会默默的扩容,然后我们vs是扩的1.5倍。在linux是默认扩的2倍。所以当我们后面在使用voector的默认构造并且需要扩大容量的时候,最好先预定一下空间的大小,
大家看看我们上面的图片,是一个对比图,一个是我们没有确定初始容量的,一个我们确定的容量的。大家不要觉得确定容量比较麻烦,但是当我们后面使用的时候就有大用的。
vector 增删查改
OK,了解了我们的空间增长问题后,我们就来学学修改空间数据的关键词。虽然我们在string的博客中没有提及,那时因为我觉得vector反正也会有相关知识的所以我就想大家先看看我发的那个链接看着,然后我在这一篇博客在说明一下,大家应该就理解的差不多了。那么我们这里就先来看看大概有哪几个关键词:
也正是我们图片上讲的,我们在vector增删查改经常用的是我们的尾插尾删。和数组下标。这个理解起来大家肯定不会很难,因为我们在c的时候应该都模拟实现过,所以我们这里就不解释了,我们就直接看看例子:
void TestVector4(){vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);auto it = v.begin();while (it != v.end()) {cout << *it << " ";++it;}cout << endl;v.pop_back();v.pop_back();it = v.begin();while (it != v.end()) {cout << *it << " ";++it;}cout << endl;}// 任意位置插入:insert和erase,以及查找find// 注意find不是vector自身提供的方法,是STL提供的算法
大家需要注意尾插与尾插开头写的是什么哈,别到时候记混了。到时候一编译牛头不对马嘴。但是我们大家需要注意一下
vector<int> a;for(int i=0;i<10;i++) a[i]=i;这种做法以及类似的做法都是错误的。我们要记得下标只能用于获取已存在的元素,而现在的a[i]还是空的对象。
void TestVector6(){vector<int> v{ 1, 2, 3, 4 };// 通过[]读写第0个位置。v[0] = 10;cout << v[0] << endl;// 使用for+[]小标方式遍历for (size_t i = 0; i < v.size(); ++i)cout << v[i] << " ";cout << endl;vector<int> swapv;swapv.swap(v);cout << "v data:";for (size_t i = 0; i < v.size(); ++i)cout << v[i] << " ";cout << endl;}
总结
我知道关于vector的内容还有很多,我们这里就简单的举了几个我们后面在学习的时候可能会经常用的的几个,这里是希望大家可以提前了解因为,知道大概有哪些和使用方法。并且我这个半吊子实操的也比较少所以这就算一个预习资料吧,然后就是大家想看vector的全部并且看看示例和解释的话,大家可以点击下面的链接,去学习学习:cplusplus.com/reference/vector/vector/