vector向量容器
1.0 vector概述:
vector向量容器,我先前见到过很多有关vector名字的定义,比如说,不定长数组,向量,可变数组等。其实,这些都是根据vector的特有性质来叫的。
它不但能像数组那样对元素来进行随机的访问,还可以再尾部插入元素,是一种高效,简单的容器,完全在一定程度上可以替代数组.
值得注意的是,vector具有内存自动管理的功能,也就是说,当我们对于新的元素要插入容器中时,可以不用手动的申请内存空间.对于旧的元素的删除,
不用刻意的delete内存空间,他可以动态调整所占的内存空间.
vector容器的下标是从0开始计数的,也就是说,如果vector容器的大小是n的话,那么,元素的下标将会从0-n-1.
对于vector大小的定义,可以事先就定义一个固定的大小,事后,随时调整他的大小。也可以不用定义他的大小,然后用push_back()从尾部
不断的扩张元素,以及用insert()在某个元素的位置前不断的插入新的元素.
1.1创建vector对象
创建vector对象常用的由三种形式.
(1)不指定vector容器的元素个数,如定义一个用来存储整形的容器.
vector<int>v;
vector<xxx>v; //xxx:可以是包含所有自带的数据类型和认为定义的数据类型
(2)创建时,制定容器的大小,比如说,我们要创建一个大小为10的用来存储double类型元素的向量容器
vector<double>v(10);
PS:元素的下标将会从0-9的变化,且每个元素的值都被初始化为0.0。
(3)创建一个具有n个元素的向量容器对象,每个元素的值都是8.6
vector<double>v(10,8.6);
这句代码是说,定义了一个名为v的vector容器,容器里有10个元素,这10个元素都是8.6
如果我们定义vector<int>v(10,8.6)的话,尝试的遍历下这个容器,我们会发现容器中的所有元素都变成了8,这也就是说,
自动将类型做了转化,vector<xxx>定义后,再加入的所有元素都会被强制转化为xxx类型的。
1.2 尾部元素的扩张
通常是用push_back()对vector容器在尾部追加新元素。尾部追加新元素时,vector会自动的为新元素来分配内存空间。并且我们还
可以对于空的vector对象来进行扩张,也可以对已有的元素的vector来进行扩张。
下面的代码是将2,7,9三个元素从尾部添加到v的容器中,这样,由于是尾部添加,所以v容器中的三个元素是2,7,9。
代码:
//cin,cout需要 # include<iostream> //vectot需要 # include<vector> //accumulate算法需要 # include<numeric> using namespace std; int main(void) { vector<int>v; v.push_back(2); v.push_back(7); v.push_back(9); vector<int>::iterator it; for ( it=v.begin();it!=v.end();it++ ) cout<<*it<<endl; return 0; }
1.3 下标方式来访问vector的元素
访问或者遍历vector中的元素是非常重要的,因为我们知道,我们要想对于一些目标数据进行我们预期的操作的话,我们就要用一个容器把他们
先存储起来,然后对于这个存储后的数据,我们要进行查询,vector查询的过程其实和数据很像,直接通过元素的下标来访问一个元素.
下面的代码是采用下标的方式来对数组进行赋值,在输出元素的值2,7,9.
代码:
//cin,cout需要 # include<iostream> //vectot需要 # include<vector> using namespace std; int main(void) { vector<int>v(3); v[0] = 2; v[1] = 7; v[2] = 9; cout<<v[0]<<endl; cout<<v[1]<<endl; cout<<v[2]<<endl; return 0; }
1.4 用迭代器访问vector元素
常需要用迭代器配合循环语句来对vector中的对象来进行遍历访问,迭代器的类型一定要与它要访问的vector对象的元素类型一致.
下面的代码采用了用vector对元素进行遍历,
//cin,cout需要 # include<iostream> //vectot需要 # include<vector> using namespace std; int main(void) { vector<int>v(3); v[0] = 2; v[1] = 7; v[2] = 9; vector<int>::iterator it; for ( it=v.begin();it!=v.end();it++ ) cout<<*it<<endl; return 0; }
1.5元素的插入
insert()方法可以在vector对象的任意一个位置前插入一个新的元素,同时,vector自动扩张一个元素的空间,插入位置后的所有元素依次向后的所有
元素依次向后挪动一个位置。
要注意的是,insert()方法是要求插入的位置,是元素的迭代器位置,而不是元素的下标位置。
下面的代码输出的结果是8,2,1,7,9,3
代码:
//cin,cout需要 # include<iostream> //vectot需要 # include<vector> using namespace std; int main(void) { vector<int>v(3); v[0] = 2; v[1] = 7; v[2] = 9; v.insert(v.begin(),8); v.insert(v.begin()+2,1); v.insert(v.end(),3); vector<int>::iterator it; for ( it=v.begin();it!=v.end();it++ ) cout<<*it<<endl; return 0; }
2.6 元素的删除
erase()方法可以删除vector中迭代器所指的一个元素或者是一段区间中的所有元素.
clear()方法可以删除vector中的所有元素.
下面的代码演示了vector元素的删除方法:
代码:
//cin,cout需要 # include<iostream> //vectot需要 # include<vector> using namespace std; int main(void) { vector<int>v(10); for ( int i = 0;i < 10;i++ ) { v[i] = i; } //删除第3个元素,因为是从0开始计数的. v.erase(v.begin()+2); vector<int>::iterator it; for ( it=v.begin();it!=v.end();it++ ) { cout<<*it<<endl; } cout<<endl; //删除第2个到第6个元素 v.erase(v.begin()+1,v.begin()+5); for ( it=v.begin();it!=v.end();it++ ) { cout<<*it<<endl; } cout<<endl; cout<<v.size()<<endl; cout<<endl; v.clear(); cout<<v.size()<<endl; return 0; }
1.7 使用reverse反向排列的算法
reverse反向排列算法需要定义头文件#include<algorithm>
reverse反向排列算法可以将向量中某段迭代器区间反向排列,开下面的代码:
//cin,cout需要 # include<iostream> //vectot需要 # include<vector> //reverse需要 # include<algorithm> using namespace std; int main(void) { vector<int>v(10); for ( int i = 0;i < 10;i++ ) { v[i] = i; } vector<int>::iterator it; //反向排列向量的从头到尾的所有元素 reverse(v.begin(),v.end()); for ( it=v.begin();it!=v.end();it++ ) cout<<*it<<endl; return 0; }
1.8 使用sort()算法对于向量元素进行排序
使用sort()和使用reverse()一样,也需要#include<algorithm>
sort算法要求使用随机访问迭代器进行排序,在默认的情况下,对向量元素进行升序排序,也就是我们说的从小到大排序,这个程序很好的说明了sort算法
的使用方法.
//cin,cout需要 # include<iostream> //vectot需要 # include<vector> //reverse需要 # include<algorithm> using namespace std; int main(void) { vector<int>v(10); for ( int i = 0;i < 10;i++ ) { v[i] = 9-i; } vector<int>::iterator it; for ( it=v.begin();it!=v.end();it++ ) cout<<*it<<endl; cout<<endl; //对于vector容器中的元素进行从小到大的排序 sort(v.begin(),v.end()); for ( it = v.begin();it!=v.end();it++ ) cout<<*it<<endl; return 0; }
上面的sort(v.begin(),v.end(), xx ); xx默认为空了,就按照了从小到大的顺序进行了排序,如果我们按照我们的要求自己写了个cmp的话,他就会按照
我们的要求对vector中的元素来进行排序了。
下面的代码是让vector中的元素来才大到小来进行排序,
//cin,cout需要 # include<iostream> //vectot需要 # include<vector> //reverse需要 # include<algorithm> using namespace std; int cmp ( const int & a,const int & b ) { return a > b; } int main(void) { vector<int>v(10); for ( int i = 0;i < 10;i++ ) { v[i] = i; } for ( int i = 0;i <10;i++ ) cout<<v[i]<<" "; cout<<endl; //按照我们写的cmp来对vector容器中的元素进行排序 sort(v.begin(),v.end(),cmp); for ( int i = 0;i < 10;i++ ) { cout<<v[i]<<" "; } cout<<endl; return 0; }
1.9 向量的大小
使用size()方法可以返回向量的大小,也就是说vector容器中元素的个数.
使用empty()方法可以返回向量是否为空.
下面的代码就演示了size()和empty()的使用方法
//cin,cout需要 # include<iostream> //vectot需要 # include<vector> //reverse需要 # include<algorithm> using namespace std; int main(void) { vector<int>v(10); for ( int i = 0;i < 10;i++ ) { v[i] = i; } for ( int i = 0;i <10;i++ ) cout<<v[i]<<" "; cout<<endl; cout<<v.size()<<endl; //注意:vector容器中没有length这个函数. //cout<<v.length()<<endl; cout<<v.empty()<<endl; v.clear(); //如果vector容器是空的话,那么就返回1,不空的话,就返回0 cout<<v.empty()<<endl; return 0; }
以上这9类都是关于vector最为简单的应用了,如果我们想要深入学习更有有关vector的内容,可以再STL详细介绍的书籍中去学习。
vector<>v ,装进容器中的元素可以是 char,string,double等更多的类型,还可以是结构体,所以使用起来非常的灵活。