C++:STL标准模板库

4.21
tips:

这个地方如果用istream_iterator<int> i2();会报错,

记住用这种格式来给容器用输入来赋初值。

内容与目标
1、泛型程序设计
2、STL结构概览
3、迭代器
4、容器的分类与基本功能
5、顺序容器
6、关联容器
7、函数对象
8、函数适配器
9、STL基本算法
------------------------初步了解泛型编程
初步了解标准模板库
初步体验用STL实施泛型编程

1、泛型程序设计:
在C++中,模板是泛型编程的基础。
基本概念:泛型编程范式GP:模板也叫参数类型多态化。泛型在“编译时期”确定,相比面向对象的虚函数多态,能够有更高的效率。
泛型编程是从一个抽象层面描述一种类型的算法,不管容器类型是什么,是一种不同于OOP的角度来抽象具体算法。

2、迭代器


a.迭代器是算法和容器的“中间人”。
b.迭代器对存储在容器中的元素序列进行遍历,提供的访问容器中每个元素的方法。
c.指针是迭代器的一种。
d.迭代器是泛化的指针,提供了类似指针的操作(诸如++、*、->运算符)。
e.迭代器不仅仅是指针:迭代器更为抽象,可以指向容器中的一个位置,通过迭代器访问这
个位置的元素,而不必关心这个位置对应的是真正的物理地址。

2、分类:
1、输入迭代器:可以用来从序列中读取数据
2、输出迭代器:允许向序列中写入数据
3、前向迭代器:既是输入迭代器又是输出迭代器,并且可以对序列进行单项的遍历。
4、双向迭代器:与前向迭代器相似,但是在两个方向上都可以对数据遍历
5、随机访问迭代器:也是双向迭代器,但是能够在序列中的任意两个位置之间进行跳转,如指针、使用vector的begin()、end()函数得到的迭代器。

说明:
1、两个迭代器表示一个区间:[p1,p2)这是一个左闭右开区间。
2、STL算法常以迭代器的区间作为输入,传递输入数据:
transform(p1,p2,.......);
transform(s.begin(),s.end());
区间包含p1,但不包含p2;

3、示例:
输入流迭代器和输出流迭代器:
□输入流、输出流
□标准类:istream、ostream
□实例:cin、cout

输入流迭代器:
□template<class T> istream_iterator<T>
□要求:T类型重载了运算符>>
▶以输入流为参数构造:
istream_iterator<int>(cin);
istream_iterator<int>(); //指向输入流结束位置
输入流迭代器:
□template<class T> ostream_iterator<T>
□要求:T类型重载了运算符<<
▶以输出流为参数构造:
ostream_iterator<int>(cout);
ostream_iterator<int>(cout,分隔符);


4、迭代器的辅助函数
1、对pos执行n次自增操作:
void advance(iterator pos,int n); //advance不检查迭代器是否超过end()
2、计算两个迭代器first和last的距离
int distance(iterator first,iterator last)
//对first执行所少次“++”操作后,能够使得first == last;

3、容器的分类与基本功能:
1、容器的分类
▶容器类是容纳、包含一组元素或元素集合的对象
▶七种基本容器:
向量(vector)
双端队列(deque)
列表(list)
集合(set)
多重集合(multiset)
映射(map)
多重映射(multimap)
▶按容器中元素的组织方式:
顺序容器
关联容器
▶按与容器相关的迭代器类型
可逆容器
随机访问容器

2、容器的通用功能:
☀用默认构造函数构造空容器
☀支持关系运算符: ==、!=、<、<=、>、>=
☀begin()、end():获得容器首、尾迭代器
☀clear():清空容器
☀empty():判断容器是否为空
☀size();得到容器元素个数
☀s1.swap(s2):将s1和s2两个容器内容交换
3、
▶随机访问容器:
支持随机访问: s[n]; 获得容器s的第n个元素
▶相关迭代器类型(s表示容器类型)
s :: iterator: 指向容器元素的迭代器类型
s :: const_iterator: 常迭代器类型-------一经初始化,无法更改

▶可逆(双向)容器的功能

说明:rend变成了元素首个元素之前的那个位置。

4、顺序容器
1、顺序容器通用:
▶构造:
S s(n,t);
S s(n);
S s(q1,q2);-----------------//q1,q2表示两个迭代器,可以把迭代器区间的元素赋值给顺序容器
▶赋值:
s.assign(n,t);
s.assign(n);
s.assign(q1,q2);
▶插入:
s.insert(pos,t);
s.insert(pos,n,t);
s.insert(pos,q1,q2);

s.push_front(t); //对list和deque
s.push_back(t);
▶ 删除



4.1 向量vector

4.2 双端队列(deque)

示例:奇偶排序:
先按照从大到小顺序输出奇数;
再按照从小到大顺序输出偶数;

4.3 列表(list)


说明:这个接合操作相当于剪切。-----对原始的数据有影响。

代码说明:
注意代码中iter2和iter3.它们两个相等,对于那个区间,虽然是左闭右开的,系统默认不生效,也就是不认可这个区间。

4.4三种顺序容器(vector、deque、list)

5、关联容器
▶关联容器的特点:
☛每个关联容器都有一个键(key)
☛每个元素按键的取值升序排列(对于一个关联容器,使用迭代器在s在区间(s.begin(),s.end()))内遍历,访问到的序列总是升序。)
▶优势
可以根据键值,高效地查找元素
▶要求:键的类型必须能够用<比较
1、int、double等基本数据类型
2、其他重载了<运算符的类型

5.1、 最简单的关联容器:集合set

算法返回一个非递减序列[first,last)中的第一个大于等于val的位置:
ForwardIter lower_bound(ForwardIter first, ForwardIter last, const_Tp& val)

算法返回一个非递减序列[first,last)中的第一个大于val的位置:
ForwardIter upper_bound(ForwardIter first, ForwardIter last, const_Tp& val)


说明:这里面的pair是一个类,r是一个对象,里面有两个成员,一个是first,一个是second,这里面的作用,第一个是迭代器,第二个是bool型,用来判断输入是否有相同元素,因为set里不能有相同的元素。

说明:在count()中,k表示key值,也就是说,在set中,count(key)只可能是1或者0;

5.2 映射(map)
▶映射与集合相同点
☛一组无重复的数据
▶映射与集合主要区别
☛集合的元素类型是键本身
☛映射的元素类型是由键和附加数据所构成的二元组:map<string,int> courses;
▶在映射中按照键查找一个元素时,除了能确定它的存在性外,还可以得到相应的附加数据。

5.3 关联容器分类

6、多重集合(multiset)与多重映射(multimap)
▶多重集合是允许有重复元素的集合
▶多重映射是允许一个键对应多个附加数据的映射

函数对象
▶函数对象
☛一个行为类似函数的对象
☛可以没有参数,也可以带有若干参数
☛其功能是获取一个值,或者改变操作的状态
▶函数对象的形式
☛普通函数就是函数对象
☛重载了“()”运算符的类的实例是函数对象

示例:定义普通函数表示乘法:

说明:累加算法accumulate
☛template<class InputIterator, class Type, class BinaryFunction>
Type accumulate( InputIterator first, InputIterator last, Type val, BinaryFunction binaryOp );
▶算法功能:
☛对[first,last)区间内的数据进行累“加”-------加只是一种操作状态
☛val为累“加”的初值
☛binaryOp为 二元函数对象,表示的“加”运算符

▶定义表示乘法的函数对象------------------通过重载类的“()”

▶STL提供的函数对象--------------------#include<functional>



☛一元函数对象:有1个参数的函数对象
☛二元函数对象:有2个参数的函数对象
☛产生器:有0个参数的函数对象

一元函数对象的应用:


二元函数对象的应用

▶函数对象概念图(谓词)

示例:


函数适配器
引入:为什么要用函数适配器?

1、使用 绑定适配器
▶将n元函数对象的指定参数绑定为一个常数,得到n-1元函数对象

vector<int>:; iterator p = find_if(a.begin(),a.end(),bind1st(greater<int>(),40));
说明:greater里面是这样的:
class greater<int>(int x,int y)
{
return (x>y);
}
如果是bind1st,就是给x绑定,也就是40>y,是找小于40的y
如果是bind2nd, 就是给y绑定,也就是x>40,是找大于40的x
其实,它返回的是一个迭代器,所以用迭代器p来接收返回的值。
▶绑定适配器
☛将一个操作数绑定到给定值而将二元函数对象转换为一元函数对象。
☛两个绑定适配器函数
☺bind2nd:将给定值绑定到二元函数对象的第二个实参;
☺bind1st:将给定值绑定到二元函数对象的第一个实参;

2、STL中函数适配器分类

ptr_fun(g):对一般函数使用,使g能成为bind2nd适配器的输入
men_fun:是成员函数作为函数对象,传入指针
men_fun_ref:是成员函数作为函数对象,传入运用。


3 、STL基本算法
▶STL算法本身是一种函数模板
☛通过迭代器获得输入数据
☛通过函数对象对数据进行处理
☛通过迭代器将结果输出
▶STL算法是通用的,独立于具体的数据类型、容器类型
▶STL算法分类
☛ 不可变序列算法
☛ 可变序列算法
☛ 排序和搜索算法
☛ 数值算法

1、不可变序列算法

2、可变序列算法:可以修改它们所操作的容器对象

3、搜索和排序算法


4、算法示例:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值