目录
前言:
在这个笔记中,我把大多数代码都加了注释,我的一些想法和注解用蓝色字体标记了出来,重点和需要关注的地方用红色字体标记了出来。
在这一篇文章中,我们主要对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 容器的基本使用方法及特性,包括一维和二维数组的实现、常用操作如 insert 和 erase 的应用,以及 deque 和 list 的特有功能。
1732

被折叠的 条评论
为什么被折叠?



