C++STL标准库学习笔记vector deque list
Posted AwakeFantasy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++STL标准库学习笔记vector deque list相关的知识,希望对你有一定的参考价值。
前言:
在这个笔记中,我把大多数代码都加了注释,我的一些想法和注解用蓝色字体标记了出来,重点和需要关注的地方用红色字体标记了出来。
在这一篇文章中,我们主要对vector deque list进行简单的介绍,(真的很简单的介绍,如果想要知道所有函数的用法的话,建议去看一下其他人的总结,我这里主要是记录一个学习过程,提供一个学习思路)
因为它们的操作大多相同,就不一个个列举它们的操作了,一个优秀的IDE能自动提示“.”后面应该接什么,函数里面应该填什么,反复强调已经了解过的知识就有点冗杂了。
正文:
1. vector示例程序
#include<iostream> #include<vector> using namespace std; template<class T> void PrintVector(T s, T e) for (; s != e; s++) cout<<* s<<" "; cout<<endl; int main(int argc, char const *argv[]) int a[5] = 1,2,3,4,5; vector<int> v(a,a+5); //用数组来构造vector cout<<"1)"<<v.end() - v.begin()<<endl;//结果:1)5 cout<<"2)"; PrintVector(v.begin(),v.end());//结果:2)1 2 3 4 5 v.insert(v.begin() + 2, 13); //在第二个元素后面插入元素 cout<<"3)"; PrintVector(v.begin(),v.end());//结果:3)1 2 13 3 4 5 v.erase(v.begin() + 2); //删除迭代器指向的元素 cout<<"4)"; PrintVector(v.begin(),v.end());//结果:4)1 2 3 4 5 vector<int> v2(4,100); //构造函数,创造四个元素值为100的vector v2.insert(v2.begin(),v.begin() + 1,v.begin() + 3);//将v的一段插入v2的开头 cout<<"5) v2:"; PrintVector(v2.begin(),v2.end());//结果:5) v2:2 3 100 100 100 100 v2.erase(v.begin()+1, v.begin()+3); //删除了v的一个区间,即2,3 cout<<"6)"; PrintVector(v.begin(),v.end());//结果:6)1 4 5 return 0;
老样子,找出其中重要的部分来细锁。
int a[5] = 1,2,3,4,5;
vector<int> v(a,a+5);
这里是建立了一个int数组,然后用这个数组来创造一个vector。
v.end() - v.begin()
这个在这个程序中的结果是5,说明vector的迭代器是随机访问迭代器,毕竟只有它才能实现加减操作。
v.insert(v.begin() + 2, 13);
在第二个元素后面插入13(不就是在下标2插入元素然后后面的元素集体后移吗),没什么需要特别强调的。
v.erase(v.begin() + 2);
删除第二个元素后面(不就是下标为2的元素吗)的元素。
vector<int> v2(4,100);
构造函数,v2包含四个值为100的元素。(充分体现了STL标准库的聪明机智,直接省去麻烦的一个个赋值)
v2.insert(v2.begin(),v.begin() + 1,v.begin() + 3);
在v2的开头插入v的下标为1到下标为2(1和3的左闭右开区间)的元素。(STL标准库普遍如此)
v2.erase(v.begin()+1, v.begin()+3);
擦去下标为1和2的元素([1,3)的元素)
2. 用vector实现二维数组
样例:
#include<iostream> #include<vector> using namespace std; int main(int argc, char const *argv[]) vector<vector<int>>v(3); //v有3个元素,每个元素都是vector<int>容器 for (int i = 0; i < v.size(); i++) for (int j = 0; j < 4; j++) v[i].push_back(j); for (int i = 0; i < v.size(); i++) for (int j = 0; j < 4; j++) cout<<v[i][j]<<" "; cout<<endl; /* 结果: 0 1 2 3 0 1 2 3 0 1 2 3 */ return 0;
从本质上来看,就是套娃,但是它的元素可以通过v[i][j]来调用,可以说是非常方便的
注意:
vector<vector<int> >v(3);
在定义时,里面的vector<int>后面要记得跟一个空格,部分编译器可能会把两个“>”号看成右移运算符
3. deque
双向队列
所有适用于vector的操作都适用于deque
deque还有push_front(将元素插入到前面)和pop_front(删除最前面的元素)操作,复杂度是O(1)
4. list容器
双向链表
它的底层实现不是数组,所以不支持随机存取
在任何位置插入删除都是常数时间,不支持随机存取
除了具有所有顺序容器都具有的成员函数以外(差不多vector有的它都有),还支持8个成员函数:
push_front:在前面插入
pop_front:删除前面的元素
sort:排序(list不支持STL的算法sort)(毕竟这是list,而不是数组之类,STL库的sort算法只支持可以随机访问的迭代器)
remove:删除和指定值相等的所有元素
unique:删除所有和前一个元素相同的元素(要做到元素不重复,则unique之前还需要sort)
merge:合并两个链表,并清空被合并的那个
reverse:颠倒链表
splice:在指定位置前面插入另一链表中的一个或多个元素,并在另一链表中删除被插入的元素
样例:
#include<list> #include<iostream> #include<algorithm> using namespace std; class A private: int n; public: A(int n_) n = n_; friend bool operator<( const A & a1, const A & a2); friend bool operator==( const A & a1, const A & a2); friend ostream & operator<<( ostream & o, const A & a); ; bool operator<(const A & a1, const A & a2) return a1.n < a2.n; bool operator==(const A & a1, const A & a2) return a1.n == a2.n; ostream & operator<<( ostream & o, const A & a) o << a.n; return o; template<class T> void PrintList(const list<T> & lst) //不推荐的写法,还是用两个迭代器作为参数会更好 typename list<T>::const_iterator i; i = lst.begin(); for ( i = lst.begin(); i != lst.end(); i++) cout<< *i << ","; //typename可以用来说明list<T>::const_iterator是个类型 //在vs中不写也可以 int main(int argc, char const *argv[]) list<A> lst1,lst2; lst1.push_back(1); lst1.push_back(2); lst1.push_back(3); lst1.push_back(4); lst1.push_back(2); lst2.push_back(10); lst2.push_front(20); lst2.push_back(30); lst2.push_back(30); lst2.push_back(30); lst2.push_front(40); lst2.push_back(40); cout<<"1)"; PrintList(lst1); cout<<endl;//输出:1)1,2,3,4,2, cout<<"2)"; PrintList(lst2); cout<<endl;//输出:2)40,20,10,30,30,30,40, lst2.sort(); cout<<"3)"; PrintList(lst2); cout<<endl;//输出:3)10,20,30,30,30,40,40, lst2.pop_front(); cout<<"4)"; PrintList(lst2); cout<<endl;//输出:4)20,30,30,30,40,40, lst1.remove(2);//删除所有和A(2)相等的元素 cout<<"5)"; PrintList(lst1); cout<<endl;//输出:5)1,3,4, lst2.unique();//删除所有和前一个元素相等的元素 cout<<"6)"; PrintList(lst2); cout<<endl;//输出:6)20,30,40, lst1.merge(lst2);//合并lst2到lst1并清空lst2 cout<<"7)"; PrintList(lst1); cout<<endl;//输出:7)1,3,4,20,30,40, cout<<"8)"; PrintList(lst2); cout<<endl;//输出:8) lst1.reverse(); cout<<"9)"; PrintList(lst1); cout<<endl;//输出:9)40,30,20,4,3,1, lst2.push_back(100); lst2.push_back(200); lst2.push_back(300); lst2.push_back(400); list<A>::iterator p1,p2,p3; p1 = find(lst1.begin(),lst1.end(),3); p2 = find(lst2.begin(),lst2.end(),200); p3 = find(lst2.begin(),lst2.end(),400); lst1.splice(p1,lst2,p2,p3); //将[p2,p3)插入p1之前,并从lst2中删除[p2,p3) cout<<"10)"; PrintList(lst1); cout<<endl;//输出:10)40,30,20,4,200,300,3,1, cout<<"11)"; PrintList(lst2); cout<<endl;//输出:11)100,400, return 0;
这个样例基本把list的主要用法都包含进去了。
后记:
这些东东基本上都是那种你知道了一个,其他的就都能推导出来的那种知识,如果不想死记硬背的话,其实用好IDE自带的功能,记好基本的用法就能自由使用了。放假了,不能摸鱼,要认真学习,为将来做好准备(生怕被淘汰的我)。
以上是关于C++STL标准库学习笔记vector deque list的主要内容,如果未能解决你的问题,请参考以下文章