C++ Templates STL标准模板库的基本概念
STL标准库包括几个重要的组件:容器、迭代器和算法。迭代器iterator,用来在一个对象群集的元素上进行遍历操作。这个对象群集或许是一个容器,或许是容器的一部分。迭代器的主要好处是,为所有的容器提供了一组很小的公共接口。利用这个接口,某项操作就可以行进到群集的下一个元素。同时每一种容器都提供了自己的迭代器,而这些迭代器了解该种容器的内部结构,所以能够知道如何正确行进。
vector是将其元素置于一个dynamic array 中加以管理。它允许随机存取,也就是说你可以利用索引直接存取任何一个元素。在array尾部附加元素或者移除元素均非常快速。但是在array中部或者头部安插元素就比较费时,因为,为了保持原本的相对次序,安插点之后的所有元素都必须移动,搬出位子来。
vector和deque都有这几个函数
push_back()向后插入元素
push_front()向前插入元素
size()成员函数返回容器中的元素个数
List由双向链表(double linked list)实作而成。这意味着list内的每个元素都以一部分内存指示其前驱元素和后继元素。List不提供随机存取,因此如果你要存取第10个元素,你必须沿着串链一次走过前9个元素。不过,移动至下一个元素或前一个元素的行为,可以在常数时间内完成。因此一般的元素存取动作会花费线性时间。这比vector和deque提供的分摊时间(amoritzed)常数时间,性能差很多。
List的优势是:在任何位置上执行安插或删除动作都非常迅速,因为只需改变链接就行。这表示在list中间位置移动元素比在vector和deque快得多。
list 函数申明:
front();
empty();
push_back();
pop_front();//并不会返回被删除的元素,所以你无法将front()和pop_front()合二为一
vector没有提供push_front(),因为其时间性能很差,在vector头端安插一个元素,需要移动全部的元素。一般而言,stl容器只提供
通常具备良好的时间效能的成员函数,这样可以防止程序员调用性能很差的函数。
#include<iostream>
#include<list>
using namespace std;
int main()
{
list<char>coll;//list container for character elements
for(char c='a';c<='z';c++)
{
coll.push_back(c);
}
while(!coll.empty())
{
cout<<coll.front()<<' ';
coll.pop_front();
}
cout<<endl;
}
也可以吧string当做STL容器来使用。这里的string是指c++string类族系(basic_string<>,string,wstring)的对象。string和vector非常相似,只不过其元素为字符。
Array容器不是类别class,而是c++语言核心所支持的一种type,具有静态大小或者动态大小的
array。但是array并非stl容器,他们并没有类似size()和empty()等成员函数。尽管如此,stl的设计允许你针对array调用stl算法,当我们以static arrays作为初始行时,这一点特别有用。
关联容器和顺序容器的本质区别:关联容器是通过键存取和读取元素、顺序容器通过元素在容器中的位置顺序存储和访问元素。因此,关联容器不提供front、push_front、pop_front、back、push_back以及pop_back,此外对于关联容器不能通过容器大小来定义,因为这样的话将无法知道键所对应的值什么。
关联式容器依据特定的排序准则,自动为其元素排序。排序准则一函数形式呈现,用来标记哦元素值(value)或者元素键(key)。缺省情况下以operator<进行比较,不过你也可以提供自己的比较函数,定义出不同的排序准则。
两个基本的关联容器类型是map和set。map的元素以键-值对的形式组织:键用作元素在map的索引,而值则表示所存储和读取的数据。set仅包含一个键,并有效地支持关于某个键是否存在的查询。set和map类型的对象不允许为同一个键添加第二个元素。如果一个键必须对应多个实例,则需使用multimap或mutiset类型,这两种类型允许多个元素拥有相同的键。
ps:所有的关联式容器都提供有一个insert()成员函数,用以安插新元素
在关联式容器中不能使用序列式容器的push_back()和push_front()函数,它们在这里毫无意义,因为你没有权利制定新元素的位置。并且要注意的是Sets不允许存在重复元素
迭代器(iterator)是一个可遍历STL容器内全部或部分元素的对象。一个迭代器用来指出容器中的一个特定位置。基本操作如下:
Operator*
返回当前位置上的元素值。如果该元素拥有成员,你可以透过迭代器,直接以operator->取用
Operator++
将迭代器前进至下一个元素。大多数迭代器还可以使用operator--退回前一个元素。
Operator==和Operator!=
判断两个迭代器是否指向同一位置
operator=
为迭代器赋值(将其所指元素的位置赋值过去)
这些操作和c++操作array元素是的指针接口一致。不同之处在于,迭代器是个所谓的smart pointer,具有遍历复杂数据结构的能力。其下层运行机制取决于其所遍历的数据结构。因此,每一种容器都需要将其迭代器以嵌套的方式定义与内部。因此各种迭代器的接口相同,型号却不同。这直接导致了泛型程序设计的概念:所有操作行为都使用相同的接口,虽然他们的型号不同。因此,你可以使用template将泛型操作公式化,使之得以顺利的运行那些能够满足接口需求的任何型别。
所有的容器类别都提供有一些成员函数,使我们得以获得迭代器并以之遍历所有的元素。这些函数中最重要的是:
begin():返回一个迭代器,指向容器起始点,也就是第一元素所在的位置。
end():返回一个迭代器,指向容器的结束点。结束点在最后一个元素之后,这样的迭代器又称为past-the-end 迭代器。
1、为遍历元素时,循环的结束时机提供了一个简单的判断依据。只要尚未到达end(),循环就可以继续
2、不必对空区间采取特殊的处理方法。空区间的begin()就等同于end();
#include<iostream>
#include<list>
using namespace std;
int main()
{
list<char>coll;
for(char c='a';c<='z';++c)
{
coll.push_back(c);
}
list<char>::const_iterator pos;
for(pos=coll.begin();pos!=coll.end(); ++pos)
{
cout<<*pos<<" ";
}
cout<<endl;
return 0;
}
任何一种容器都定义有两种迭代器型别:
1、container::iterator
这种迭代器以“读/写”的模式遍历元素
2、container::const_iterator
这种迭代器以”只读“模式
在循环内部,语句*pos代表当前的元素。本例将它输出之后,又接着输出了一个空格。你不能改变元素内容,以为pos是个const_iterator,从迭代器的观点看去,元素是常量,不能改变。不过如果拟采用非常量(nonconstant)迭代器,而且元素本身的型别也是非常量,那么就可以透过迭代器来改变元素的值。
list<char>::iterator pos;
for(pos=coll.begin();pos!=coll.end();++pos)
{
*pos=toupper(*pos);
}//最好使用++pos,不要使用pos++
我们也可以采用list例中所用的相同循环来打印set内的元素。以一个迭代器遍历全部元素,并且逐一打印出来:
IntSet::const_iterator pos;
for(pos=coll.begin();pos!=coll.end();++pos)
{
cout<<*pos<<" ";
}
由于迭代器是容器定义的,所以无论容器内部结构如何复杂,它都知道如何行事。举个例子,如果迭代器指向第三个元素,操作符++便会将它移动到上端的第四个元素,再一次++,便会将它移动到下方的第五个元素。
set中元素输出默认是从小到大(set不可以有重复元素) 如这个set的输出结果就是:1 2 3 4 5 6
#include<iostream>
#include<set>
using namespace std;
int main()
{
typedef set<int>IntSet;//元素型别为int的一个set
IntSet coll;
coll.insert(1);
coll.insert(3);
coll.insert(5);
coll.insert(4);
coll.insert(1);
coll.insert(6);
coll.insert(2);
IntSet::const_iterator pos;
for(pos=coll.begin();pos!=coll.end();pos++)
{
cout<<*pos<<" ";
}
cout<<endl;
return 0;
}
set中的元素组织形式都是一种类似二叉树的依次排列
由于multiset允许元素重复存在,因此其中可包含两个数值相同的元素
新元素会根据排序准则自动安插到正确的位置。但是,你不能使用序列式容器的push_back()和push_front()函数,在这里毫无意义,因为你没有权利指定新元素的位置。
Maps和Multimaps的运用实例
Map的元素是成对的键值/实值(key/value)。因此其申明、元素安插、元素存取皆和set有所不同。下面是一个multimap的运用实例
#include<iostream>
#include<map>
#include<stirng>
using namespace std;
int main()
{
typedef multimap<int,stirng> IntStringMMap;
IntStringMMap coll;
coll.insert(make_pair(5,"tagged"));
coll.insert(make_pair(2,"a"));
coll.insert(make_pair(1,"this"));
coll.insert(make_pair(4,"of"));
coll.insert(make_pair(6,"strings"));
coll.insert(make_pair(1,"is"));
coll.insert(make_pair(3,"multimap"));
IntStringMMap::iterator pos;
for(pos=coll.begin();pos!=coll.end();++pos)
{
cout<<pos->second;
}//不过由于this和is的键值相同,两者的出现顺序也可能反过来
cout<<endl;
}
输出结果:this is a multimap of tagged strings
//c++标准程序库凡是必须返回两个值的函数,也都会利用pair对象。pair可以将两个值视为一个单元。容器类别map和multimap就是使用pairs来管理其健值/实值(key/value)的成对元素
pair的实现是一个结构体,主要的两个成员变量是first second, 因为是使用struct不是class,所以可以直接使用pair的成员变量。
C++ Templates STL标准模板库的基本概念的更多相关文章
- STL标准模板库(简介)
标准模板库(STL,Standard Template Library)是C++标准库的重要组成部分,包含了诸多在计算机科学领域里所常见的基本数据结构和基本算法,为广大C++程序员提供了一个可扩展的应 ...
- STL标准模板库介绍
1. STL介绍 标准模板库STL是当今每个从事C++编程的人需要掌握的技术,所有很有必要总结下 本文将介绍STL并探讨它的三个主要概念:容器.迭代器.算法. STL的最大特点就是: 数据结构和算法的 ...
- STL学习系列一:STL(标准模板库)理论基础
STL(Standard Template Library,标准模板库)是惠普实验室开发的一系列软件的统称.现然主要出现在C++中,但在被引入C++之前该技术就已经存在了很长的一段时间. STL的从广 ...
- STL(标准模板库)理论基础,容器,迭代器,算法
基本概念 STL(Standard Template Library,标准模板库)是惠普实验室开发的一系列软件的统称.现然主要出现在C++中,但在被引入C++之前该技术就已经存在了很长的一段时间. ...
- STL(标准模板库)基本概念
一.什么是STL STL(Standard Template Library,标准模板库)的从广义上讲分为三类:algorithm(算法).container(容器)和iterator(迭代器),容器 ...
- STL标准模板库 向量容器(vector)
向量容器使用动态数组存储.管理对象.因为数组是一个随机访问数据结构,所以可以随机访问向量中的元素.在数组中间或是开始处插入一个元素是费时的,特别是在数组非常大的时候更是如此.然而在数组末端插入元素却很 ...
- STL标准模板库之vector
目录 vector容器 1)什么是vector 2)如何定义 3)常用的Vector函数 1.容量函数 2.增加函数 3.删除函数 4.迭代器 5.访问函数 6.其他函数及操作 7.算法 STL提供了 ...
- STL(标准模板库) 中栈(stack)的使用方法
STL 中栈的使用方法(stack) 基本操作: stack.push(x) 将x加入栈stack中,即入栈操作 stack.pop() 出栈操作(删除栈顶),只是出栈,没有返回值 stack.t ...
- STL 标准模板库
<vector> 可变长的数组 Vector<int>v int是一个模板参数,这样传进来的都会是int V.push_back(a)将a传进v,且放在最后一个 V.clear ...
随机推荐
- Codeforces 551 E - GukiZ and GukiZiana
E - GukiZ and GukiZiana 思路:分块, 块内二分 代码: #pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC ...
- C#数组维数及不同维数中元素个数的获取
简单理解有关数组维数的概念: 1.编程中用到的多维的数组,最多也就是二维数组了 2.数组的维数从0开始计算 using System; using System.Collections.Generic ...
- 日常英语---十二、MapleStory/Monsters/Level 1-10(Horny Mushroom)
日常英语---十二.MapleStory/Monsters/Level 1-10(Horny Mushroom) 一.总结 一句话总结: horny-['hɔːnɪ]-adj.角的 Another m ...
- springBoot springSecurty: x-frame-options deny禁止iframe调用
springBoot springSecurty: x-frame-options deny禁止iframe调用 https://blog.csdn.net/whiteforever/article ...
- Android的组件化和模块化
Android随着业务的增多,而且后续新的需求的增加,代码的修改会变得非常频繁 然后最近在看组件化和模块化 公司的业务没有那么大,所以这种方式我并没有采取 但是还是需要了解下他的使用机制 还有优缺点之 ...
- Xpath做数据解析
xpath是一个路径表达式, xpath学习 (1)xpath节点 在XPath中,有七种类型的节点:元素,属性,文本,命名空间,处理指令,注释以及文档节点:XML文档是被作为节点树来对待的.树的根被 ...
- 『TensorFlow』SSD源码学习_其八:网络训练
Fork版本项目地址:SSD 作者使用了分布式训练的写法,这使得训练部分代码异常臃肿,我给出了部分注释.我对于多机分布式并不很熟,而且不是重点,所以不过多介绍,简单的给出一点训练中作者的优化手段,包含 ...
- 『TensorFlow』分布式训练_其三_多机分布式
本节中的代码大量使用『TensorFlow』分布式训练_其一_逻辑梳理中介绍的概念,是成熟的多机分布式训练样例 一.基本概念 Cluster.Job.task概念:三者可以简单的看成是层次关系,tas ...
- apache配置一个域名读取多个路径代码(包括主干和分支)
<VirtualHost *:80> ServerAdmin 651629095@qq.com DocumentRoot "C:/wamp/www/sms/trunk/publi ...
- 链接SQL Server服务器
链接SQL Server服务器: 1.使用 ODBC 的 Microsoft OLE DB 提供程序 EXEC sp_addlinkedserver '别名','','MSD ...