STL(模板库)
STL是Standard Template Library的简称,中文名标准模板库。
STL 主要由迭代器、算法、容器、仿函数、内存配置器和配接器六部分组成,可帮助程序员完成许多功能完善、形式多样的程序。
容器:各种数据结构,如vector、list、queue、stack、set、map等,用来存放数据,相当于模板类。
算法:各种常用的算法,如sort、find、copy、for_each。从实现的角度来看,STL算法是一种function tempalte.
迭代器:要访问顺序容器和关联容器中的元素,需要通过“迭代器(iterator)”进行。迭代器是一个变量,相当于容器和操纵容器的算法之间的中介。迭代器可以指向容器中的某个元素,通过迭代器就可以读写它指向的元素。从这一点上看,迭代器和指针类似。
仿函数:行为类似函数,可作为算法的某种策略。从实现角度来看,仿函数是一种重载了operator()的class 或者class template
适配器:一种用来修饰容器或者仿函数或迭代器接口的东西。
空间配置器:负责空间的配置与管理。从实现角度看,配置器是一个实现了动态空间配置、空间管理、空间释放的class tempalte.
这里主要介绍一下常用的容器、算法和迭代器。
容器
STL 准备了两类共七种基本容器类型:
序列式容器和关联式容器;
- 序列式容器:其中每个元素均有固定位置—取决于插入时机和地点,和元素值无关。如果你以追加方式对一个群集插入六个元素,它们的排列次序将和插入次序一致。STL提供了三个序列式容器:向量(vector)、双端队列(deque)、列表(list),此外你也可以把string和array 当做一种序列式容器。
- 关联式容器(Associative containers):元素位置取决于特定的排序准则以及元素值,和插入次序无关。如果你将六个元素置入这样的群集中,它们的位置取决于元素值,和插入次序无关。STL提供了四个关联式容器:集合(set)、多重集合(multiset)、映射(map)和多重映射(multimap)。
序列式容器:
vector(向量):和数组差不多,但它可以动态扩展(动态数组)。
例:
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
for (int i = 0; i < v.size(); i++) {
cout << v[i] << " ";
}
cout << endl;
return 0;
}
deque(double-ended queue):双端队列容器。和vector类似,支持随机访问和快速插入删除,它在容器中某一位置上的操作所花费的是线性时间。与vector不同的是,deque还支持从开始端插入数据:push_front()。详细介绍。
list:双向链表。
例:
#include <iostream>
#include <list>
using namespace std;
int main()
{
list<int> a;
a.push_back(1);
a.push_back(2);
a.push_back(3);
a.push_back(4);
a.push_back(5);
//a.insert(++a.begin(), 10);
//a.insert(a.begin(), 10);
a.insert(a.begin(), 3,6);//在队首添加3个6;
list<int>::iterator i = a.begin();
for (i; i != a.end(); i++) {
cout << *i << " ";
}
cout << endl;
}
关联式容器:
set(集合):内部采用的就是一种非常高效的平衡检索二叉树:红黑树,也成为RB树(Red-Black Tree)。在set中每个元素的值都唯一,而且系统能根据元素的值自动进行排序。
#include <iostream>
#include <set>
using namespace std;
int main()
{
set<int> s;
s.insert(1);
s.insert(2);
s.insert(3);
s.insert(1);
cout << "set 的 size 值为 :" << s.size() << endl;
cout << "set 的 maxsize的值为 :" << s.max_size() << endl;
cout << "set 中的第一个元素是 :"<< *s.begin() << endl;
cout << "set 中的最后一个元素是:" << *(--s.end()) << endl;
s.clear();
if (s.empty())
{
cout << "set is empty" << endl;
}
cout << "set 的 size 值为 :" << s.size() << endl;
cout << "set 的 maxsize的值为 :" << s.max_size() << endl;
return 0;
}
map:由红黑树实现,元素以键值对形式存在。每一个键只能出现一次,不允许重复。map 主要用于资料一对一映射的情况,map 内部自建一颗红黑树,这颗树具有对数据自动排序的功能,所以在 map 内部所有的数据都是有序的。比如一个班级中,每个学生的学号跟他的姓名就存在着一对一映射的关系。
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main(int argc, char* argv[])
{
map<int, string> mapTemp;
mapTemp.insert({ 5,"张三" });
mapTemp.insert({ 3, "李四" });
mapTemp.insert({ 4, "隔壁老王" });
map<int, string>::iterator it;
for (it = mapTemp.begin(); it != mapTemp.end(); it++)
{
printf("学号:%d 姓名:%s\n", (*it).first, (*it).second.c_str());
}
return 0;
}
multimap:和map差不多,但允许元素重复。详细点击。
算法
太多了,要用的时候再查吧。
可参考:http://c.biancheng.net/stl/algorithms/
迭代器
要访问顺序容器和关联容器中的元素,需要通过“迭代器(iterator)”进行。迭代器是一个变量,相当于容器和操纵容器的算法之间的中介。迭代器可以指向容器中的某个元素,通过迭代器就可以读写它指向的元素。从这一点上看,迭代器和指针类似。
- 正向迭代器,定义方法如下:
容器类名::iterator 迭代器名;
- 常量正向迭代器,定义方法如下:
容器类名::const_iterator 迭代器名;
- 反向迭代器,定义方法如下:
容器类名::reverse_iterator 迭代器名;
- 常量反向迭代器,定义方法如下:
容器类名::const_reverse_iterator 迭代器名;
通过迭代器可以读取它指向的元素,*迭代器名就表示迭代器指向的元素。通过非常量迭代器还能修改其指向的元素。
迭代器都可以进行++操作。反向迭代器和正向迭代器的区别在于:
- 对正向迭代器进行++操作时,迭代器会指向容器中的后一个元素;
- 而对反向迭代器进行++操作时,迭代器会指向容器中的前一个元素。
上面有些容器例子中有用迭代器,此处不再举例。详细点击。
注:begin成员函数返回指向容器中第一个元素的迭代器,而end成员函数返回的不是指向最后一个元素的迭代器,而是指向最后一个元素后面的位置的迭代器
--参考:https://www.cnblogs.com/linuxAndMcu/p/10254542.html#top