vector 算是一种向量类型,像容器一样能够存放任意类型的动态数组,能够增加和减少数据不像数组只能是静态空间,而 vector 的实现就是用的指针。
vector 在 C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板库和函数类。
使用前应该在头文件中声明,即:#include<vector>
然后在代码使用前面加上定义,即:vector<type> v;
虽然 vector 是一维动态数组,但是我们可以用类似于数组的思路,给他开两维
形似:
vector< vector<int> > v;
注意:
所谓动态增加大小,并不是在原空间之后续接新空间(因为无法保证原空间之后尚有可配置的空间),而是一块更大的内存空间,然后将原数据拷贝新空间,并释放原空间。因此,对vector的任何操作,一旦引起空间的重新配置,指向原vector的所有迭代器就都失效了。
大部分常用的如下:
#include<iostream> #include<cmath> #include<cstring> #include<cstdio> #include<algorithm> #include<vector> using namespace std; int a[]={1,2,3,4,5}; vector<int> v; //常规的创建 vector vector<int> v1(a,a+sizeof(a)/sizeof(int)); //将 a[begin(),end())区间中的元素拷贝给本身 vector<int> v2(10,1); //构造一个有 n 个元素的容器(实质是将 n 个元素拷贝给本身) int main(){ cout<<"v v1 v2这三个容器中分别存有的元素个数:"<<endl; cout<<v.size()<<" "<<v1.size()<<" "<<v2.size()<<endl; //size() 返回容器中元素的个数 if(v.empty()) cout<<"v.empty()==1 v这里面没有元素"<<endl; //empty() 判断 v 容器内是否空,是返回 1,否返回 0,即是 bool 类型的函数 v.push_back(a[0]); cout<<"v.push_back(a[0]) 此时v容器里面插入了a[0]"<<endl; //push_back() 尾部插入一个元素 if(!v.empty()) cout<<"!v.empty()==1 v这里面有元素"<<endl; v.insert(v.end(),a[1]); cout<<"用 v.insert() 在容器末尾插入一个 a[1]"<<endl; /* insert() 代表在 v 容器某个位置插入了一个元素 其中 insert() 里面有三个参数,(pos,number,element) 即:在 pos 位置插入了 number 个 element */ cout<<"此时 v 容器里面元素的个数为:"<<v.size()<<endl; cout<<"v 容器最前面的数为: "<<v.front()<<endl<<"v 容器最后面的数为: "<<v.back()<<endl; //front()返回容器中第一个数据元素,back()返回容器中最后一个数据元素 v.resize(4); //resize() 是重新指定容器长度的函数,有两个参数,第一个参数是重新指定的长度,第二个是需要填充的元素,第二个不填则默认为0 cout<<"我们再把 v 容器重新指定长度为 4"<<endl; cout<<"此时 v 容器的长度为: "<<v.size()<<endl; cout<<"我们把重新指定长度的 v 容器输出一次看看"<<endl; vector<int>::iterator i; //这是使用 vector 迭代器访问元素 类似于指针 cout<<"v 容器从头到尾依次为: "; for(i=v.begin();i!=v.end();i++) cout<<*i<<" "; //可见当重新指定长度的时候多出来的位置用默认数值填充时为零 cout<<"现在指定删除第一个元素"<<endl; v.erase(v.begin()); //erase() 有两个参数,posl和posr,如果只有posl则只删除该位置的元素,而posl和posr都有的情况下则删除区间元素 cout<<"此时 v 容器的长度为: "<<v.size()<<endl; cout<<"v 容器从头到尾依次为: "; for(i=v.begin();i!=v.end();i++) cout<<*i<<" "; cout<<endl; v.resize(5,5); cout<<"我们现在把 v 容器重新指定长度为 5,并且把填充的数字改为 5"<<endl; cout<<"v 容器从头到尾依次为: "; for(i=v.begin();i!=v.end();i++) cout<<*i<<" "; cout<<endl; cout<<"现在删除最后一个元素,但用的是 pop_back"<<endl; v.pop_back(); //pop_back() 删除最后一个元素 cout<<"v 容器从头到尾依次为: "; for(i=v.begin();i!=v.end();i++) cout<<*i<<" "; cout<<endl; system("pause"); }
其他用法:
#include<iostream> #include<vector> using namespace std; vector<int> v,v1; int a[5]={1,2,3,4,5}; int main(){ v.assign(a,a+sizeof(a)/sizeof(int)); // assign() 将 a 数组中的数据元素拷贝到容器中 v1.assign(3,1); //assign() 将 n 个元素拷贝到容器中 vector<int>::iterator it; cout<<"v 容器中含有的元素为: "; for(it=v.begin();it!=v.end();it++) cout<<*it<<" "; cout<<endl; cout<<"v1 容器中含有的元素为: "; for(it=v1.begin();it!=v1.end();it++) cout<<*it<<" "; cout<<endl; v.swap(v1); //swap() 将 v 和 v1 两个容器的元素互换 cout<<"使用 v.swap(v1)"<<endl; cout<<"v 容器中含有的元素为: "; for(it=v.begin();it!=v.end();it++) cout<<*it<<" "; cout<<endl; cout<<"v1 容器中含有的元素为: "; for(it=v1.begin();it!=v1.end();it++) cout<<*it<<" "; cout<<endl; v.clear(); v1.clear(); //clear()删除容器中所有元素 cout<<"此时 v 和 v1 中含有的元素个数为: "; cout<<v.size()<<" "<<v1.size()<<endl; return 0; }
对于 algorithm 里面的 sort 和 reverse 也同样适用,比如
#include<iostream> #include<vector> #include<algorithm> using namespace std; vector<int> v,v1; int a[5]={1,3,2,5,4}; int main(){ v.assign(a,a+sizeof(a)/sizeof(int)); cout<<"v 容器中含有的元素为: "; vector<int>::iterator it; for(it=v.begin();it!=v.end();it++) cout<<*it<<" "; cout<<endl; reverse(v.begin(),v.end()); cout<<"v 容器中含有的元素为: "; for(it=v.begin();it!=v.end();it++) cout<<*it<<" "; cout<<endl; sort(v.begin(),v.end()); cout<<"v 容器中含有的元素为: "; for(it=v.begin();it!=v.end();it++) cout<<*it<<" "; cout<<endl; return 0; }
当然除了这些之外还有一些操作,但我也没用过,所以在此不再赘述。
我们可以总结一下:
此处借用了 沉晓前辈的【C/C++】STL详解
vector<T> v; //采用模板实现类实现,默认构造函数 vector(v.begin(), v.end());//将v[begin(), end())区间中的元素拷贝给本身。 vector(n, elem);//构造函数将n个elem拷贝给本身。 vector(const vector &vec);//拷贝构造函数。 //例子 使用第二个构造函数 我们可以... int arr[] = {2,3,4,1,9}; vector<int> v1(arr, arr + sizeof(arr) / sizeof(int));
assign(beg, end);//将[beg, end)区间中的数据拷贝赋值给本身。 assign(n, elem);//将n个elem拷贝赋值给本身。 vector& operator=(const vector &vec);//重载等号操作符 swap(vec);// 将vec与本身的元素互换。
size();//返回容器中元素的个数 empty();//判断容器是否为空 resize(int num);//重新指定容器的长度为num,若容器变长,则以默认值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。 resize(int num, elem);//重新指定容器的长度为num,若容器变长,则以elem值填充新位置。如果容器变短,则末尾超出容器长>度的元素被删除。 capacity();//容器的容量 reserve(int len);//容器预留len个元素长度,预留位置不初始化,元素不可访问。
at(int idx); //返回索引idx所指的数据,如果idx越界,抛出out_of_range异常。 operator[];//返回索引idx所指的数据,越界时,运行直接报错 front();//返回容器中第一个数据元素 back();//返回容器中最后一个数据元素
insert(const_iterator pos, int count,ele);//迭代器指向位置pos插入count个元素ele. push_back(ele); //尾部插入元素ele pop_back();//删除最后一个元素 erase(const_iterator start, const_iterator end);//删除迭代器从start到end之间的元素 erase(const_iterator pos);//删除迭代器指向的元素 clear();//删除容器中所有元素
#include<iostream> #include<vector> #include<algorithm> using namespace std; vector<int> v,v1; int a[5]={1,3,2,5,4}; int main(){ v.assign(a,a+sizeof(a)/sizeof(int)); //方法一:使用迭代器访问元素 vector<int>::iterator it; for(it=v.begin();it!=v.end();it++) cout<<*it<<" "; cout<<endl; //方法二:用 at() 函数 for(int i=0;i<v.size();i++) cout<<v.at(i)<<" "; cout<<endl; for(int i=0;i<v.size();i++) cout<<v[i]<<" "; cout<<endl; return 0; }
这是一个非常好用的方法
#include<iostream> #include<vector> #include<algorithm> using namespace std; struct edge{ int to; int val; }e; vector<edge> v[10100]; int n,m,x,y,w; int main(){ cin>>n>>m; for(int i=1;i<=m;i++){ cin>>x>>e.to>>e.val; v[x].push_back(e); } for(int i=1;i<=n;i++){ for(int j=0;j<v[i].size();j++){ e=v[i][j]; printf("from %d to %d, the cost is %d\n",i,e.to,e.val); } } }
图论学习笔记 - 链表与邻接表
样例输入:
5 5
1 2 1
2 3 2
3 4 3
4 5 4
1 5 5
样例输出:
from 1 to 2, the cost is 1
from 1 to 5, the cost is 5
from 2 to 3, the cost is 2
from 3 to 4, the cost is 3
from 4 to 5, the cost is 4