C++ STL结构总结
1. 什么是STL
它的全名是stand template library, 标准模板库,主要是将一些结构和算法写成模板,以便能够实现对任意类型的对象都可以操作,而不需要再一次去写一些算法及结构。
它主要有以下三个概念:
容器--容纳各种数据类型的结构,是类模板
迭代器--类似于指针,指向容器内的对象的指针,主要用于指向元素
算法--操作容器内的元素的运算函数,是函数模板,比如sort,find等排序算法,查找 算法,它与容器内元素类型无关
2. 容器
用于存放数据的容器可以分为三大类,顺序容器,关联容器,容器适配器:
顺序容器--vector, list, deque
关联容器--map, multimap, set, multiset
容器适配器--stack, queue, priority_queue
2.1 顺序容器
顺序容器是无序的,插入的元素位置与值无关。
vector容器,头文件<vector>, 是一个动态数据,元素在内存中是连续存放的,可以随意取vector中的元素。
deque, 头文件<deque>, 是一个双向队列,元素在内存中连续存放,可任意取容器中的元素,与vector中不一样的是,它存在一个头指针和一个尾指针,如
list, 头文件<list>, 是一个双向链表,元素内存中不连续存放,易添加删除元素,不可随意存取元素。
2.2 关联容器
关联容器是有序的,插入元素的同时对新加元素进行排序,如何排序取决于元素类中<符号的成员函数重载, 所有的容器都是以平衡二叉树来实现,查找时间为O(lgn).
set/multiset, 头文件<set>, 又称集合,两者唯一的区别是set不允许多个元素相等,而multiset则可以存放多个相等的元素,至于两个元素相等的定义为:
如元素A不小于元素B,也不大于B,则A与B相等。因此在此仍需要重载容器内元素类的<符号函数,才能让容器函数对元素进行大小比较。
map/multimap, 头文件<map>, 又称字典,元素内存在两个成员变量:first与second,它们一一对应,容器内以first的大小进行排序,first为key,second为first对应的值。multimap允许存在first相同的元素,而map则要求所有的元素first中值唯一。
2.3 容器适配器
stack,头文件<stack>, 栈,遵守先进后出的规则
queue,头文件<queue>, 队列, 元素先进先出,如图
priority_queue, 优先级队列,头文件<queue>, 内部以一定的顺序排列,优先级最高的元素第一个出列。
2.4 容器中的成员函数
顺序容器与关联容器的公有成员函数:
begin-- 返回指向第一个元素的迭代器
end--返回指向最后一个元素的后一个迭代器
rbegin--返回指向最后一个元素的迭代器
rend--返回指向第一个元素的前一个迭代器
erase -- 删除容器中的一个或几个元素
clear -- 删除容器内所有的元素
顺序容器的成员函数:
front -- 返回第一个元素的引用
back -- 返回最后一个元素的引用
push_back -- 在容器尾添加新元素
pop_back -- 删除容器尾的元素
erase -- 删除迭代器指向的元素或一个区间内的所有元素,返回删除元素的下一个元素的迭代器
顺序容器list的成员函数:
push_front: 在链表最前面插入元素
pop_front: 删除链表最前面的元素
sort : 排序
reverse : 反转链表
remove: 删除所有与指定值相等的元素
unique: 删除所有与前一元素值相等的元素
merge : 合并链表,并清空被合并链表
splice : 在指定位置插入另一链表的一个或多个元素,并删除原来链表中的被插入元素
注意: list的sort函数与vertor中的sort函数不同,主要是因为他们之间的迭代器不一样,现在看list的sort函数定义,
list<T> lt;
lt.sort(compare); //compare is a self defined function for comparing item T
lt.sort(); // sort abided by symbol <, so we must redefined it in class T.
容器适配器的成员函数:
push : 添加元素
top : 返回栈顶或队头青元素引用
pop : 删除一个元素
3. 迭代器
类似于指针的用法,主要用于指向元素对象的位置,其定义如下:
容器类名::iterator it;
容器类名::const_iterator it; //常量迭代器,不可修改对象的值
容器类名::reverse_iterator it; //反向迭代器, it++指向前一个元素,如果是正向迭代器,则指向下一个元素
比较特殊的迭代器就是随机迭代器,可以进行操作 it + i, 直接跳进i个元素
4. STL算法
就是一些常用的数据结构算法,实现成各种模板函数,如min, max, find, find_if等等,由于此类函数太多,如果不常用,即使记住了也会容易忘掉。因此最好的办法就是理解他们实现的原理和方法,据我个人总结,可以分为以下几大类,其实如果仔细想想,可能会发现STL算法中的思想已经体现在上面的分类列举中了。
算法, 也就是用模板实现的一些通用函数,即函数模板,可以操作任意类型(常用的int, double,自定义的类等,在这可以用模板类代替实现)。而通用的函数的功能无外乎就那么几样,比如说求最小值,最大值,排序,列表求和等,然而要想实现这些功能(假设排序),函数必须知道如何判断两个元素之间的大小才能进行排序,这里可分为两个版本, 在这以max_element为例,它的两个版本的定义如下:
iterator max_element(iterator first, iterator last); //求区间[first,last)之间最大的迭代值, 默认的大小比较为 < 符号, 需要在元素对象里重载
iterator max_element(iterator first, iterator last, Pred op);// op 为一个函数指针或函数对象,if op(x,y)为真,则表示x<y, 该函数由自己定义,也可奖类对象重载()成员函数来实现。
STL算法共包括3大类,常用函数方法,操作对象及操作对象的指针,即算法函数,模板类,迭代器。迭代器可以理解成指针,可以不管,现在我们已经明白了算法函数与模板类的分工,那就好办了。只要我们了解了算法函数的定义,即它的参数定义,我们就可以用它来处现模板类,而在模板类中只需要重载一些符号的成员函数即可,据个人认为,STL算法的核心就是模板类的符号重载,这不但保证了算法使用的灵活性和通常用,也能够让程序员实现一些特别的操作。
在这里借用别人的一个例子,主要功能是用STL中的copy函数来实现打印数组,感觉比较好玩而且实用, 实现我们来看copy()函数的定义及源码实现。
template<class InIt, class OutIt>
OutIt copy(InIt first, InIt last, OutIt out)
copy区间[first, last)到out, 对区间内的所有元素都执行一次
*(out+N) = *(first+N), 并返回out+N
copy源代码
template<class __II, class __OI>
inline __OI copy(__II __f, __II __l, __OI __x)
{
for ( ; __f != __l; ++__f, ++__x)
*__x = *__f;
return __x;
}
定义一个ostream_iterator<int>对象,然后 通过cout输出一个个整数并以*号来分隔。
ostream_iterator<int> output(cout,"*");
copy(v.begin(), v.end(), output); // v为一个vector可变数组
问题:copy函数如何才能将v中的数字打印出来呢?
从源代码我们看出,里面的复制操作主要用到了++__x, *__x, =符号,而__x的类型原型实例化后就是ostream_iterator<int>, 因此只要重载了++,= , * 符号成员函数就可以达到刚才的要求了。
首先自定义一个myostream类
#include <iterator>
template<class T>
class my_osit:public iterator<output_iterator_tag,T>
{
private:
string sep;
ostream &os; //可用于写入文件
public:
my_osit(ostream &o, string s):os(o), sep(s){}
void operator++(){}
my_osit & operator*() {return *this;}
my_osit & operator=(const T val)
{
os << val << sep;
return *this;
}
}
总得来说,STL算法很强大,如果能记住当然最好,如果记不住,如果学会 了查接口,灵活运用符号重载,写程序一样轻松。
C++ STL结构总结的更多相关文章
- STL 结构体 内部函数
typedef struct Node { int val; string name; bool operator < (const Node &right) const { retur ...
- L2-3. 悄悄关注【STL+结构体排序】
L2-3. 悄悄关注 时间限制 150 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 新浪微博上有个“悄悄关注”,一个用户悄悄关注的人,不出现在 ...
- STL 结构体内重载 一个比较运算符
struct node { ll a, b; bool operator< (const node &c)const{ return a < c.a; } }pre[eps];
- C++ STL自学总结,仅供参考
本文内容,为博主在网上看到资料总结整合而来 一.stl格式简介 .stl文件是在计算机图形应用系统,来表示封闭的面或者体,用来表示三角形网格的一种文件格式.为STereo Lithography的缩写 ...
- C++11初始化列表
[C++11之初始化列表] 在C++03中,在严格遵守POD的定义和限制条件的结构及类型上可以使用初始化列表(initializer list),构想是结构或是数组能够依据成员在该结构内定义的顺序通过 ...
- windbg(1)
1.http://www.cnblogs.com/huangyong9527/category/384128.html 2.http://www.cnblogs.com/pugang/category ...
- CAF(C++ actor framework)(序列化之结构体,任意嵌套STL)(一)
User-Defined Data Types in Messages(用户自定义类型)All user-defined types must be explicitly “announced” so ...
- QT:用QSet储存自定义结构体的问题——QSet和STL的set是有本质区别的,QSet是基于哈希算法的,要求提供自定义==和qHash函数
前几天要用QSet作为储存一个自定义的结构体(就像下面这个程序一样),结果死活不成功... 后来还跑到论坛上问人了,丢脸丢大了... 事先说明:以下这个例子是错误的 #include <QtCo ...
- c++ STL map 结构体
Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据处理能力,由于这个特性,它完成有可能在我们处理一对一数据的时候 ...
随机推荐
- python 中的queue 与多进程--待继续
一.先说说Queue(队列对象) Queue是python中的标准库,可以直接import 引用,之前学习的时候有听过著名的“先吃先拉”与“后吃先吐”,其实就是这里说的队列,队列的构造的时候可以定义它 ...
- CF#498 1006F Xor-Paths
题意:一个n * m的矩阵,求从左上走到右下经过的数异或和为k的方案数. 题解: 因为数据范围较小,所以我们可以采用meet in the middle过掉此题... 然而define inf LL ...
- [bzoj] 1588 营业额统计 || Splay板子题
原题 给出一个n个数的数列ai ,对于第i个元素ai定义\(fi=min(|ai-aj|) (1<=j<i)\),f1=a1,求\(/sumfi\) Splay板子题. Splay讲解:h ...
- 洛谷 P1966 火柴排队 解题报告
P1966 火柴排队 题目描述 涵涵有两盒火柴,每盒装有 \(n\) 根火柴,每根火柴都有一个高度. 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 两列火柴之间的距离定义为: \(\s ...
- 洛谷 P2324 [SCOI2005]骑士精神 解题报告
P2324 [SCOI2005]骑士精神 题目描述 输入输出格式 输入格式: 第一行有一个正整数T(T<=10),表示一共有N组数据.接下来有T个5×5的矩阵,0表示白色骑士,1表示黑色骑士,* ...
- POJ.1061 青蛙的约会 (拓展欧几里得)
POJ.1061 青蛙的约会 (拓展欧几里得) 题意分析 我们设两只小青蛙每只都跳了X次,由于他们相遇,可以得出他们同余,则有: 代码总览 #include <iostream> #inc ...
- 剑桥offer(31~40)
31.题目描述 统计一个数字在排序数组中出现的次数. 思路:找到最低和最高,相减 class Solution { public: int GetNumberOfK(vector<int> ...
- 洛谷P1667/[10.22 模拟赛] 数列 (思维+模拟)
洛谷P1667 数列 题目描述 给定一个长度是n的数列A,我们称一个数列是完美的,当且仅当对于其任意连续子序列的和都是正的.现在你有一个操作可以改变数列,选择一个区间[X,Y]满足\(A_X +A_{ ...
- MyBatis插件及示例----打印每条SQL语句及其执行时间
Plugins 摘一段来自MyBatis官方文档的文字. MyBatis允许你在某一点拦截已映射语句执行的调用.默认情况下,MyBatis允许使用插件来拦截方法调用 Executor(update.q ...
- [LeetCode] 18. 4Sum ☆☆
Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = tar ...