STL(6)-容器的共通能力,各个容器的使用时机,常见算法用法介绍

所有容器提供的都是值(value)的语意,而非引用(reference)语意。容器执行插入元素的操作时,内部实施拷贝动作。所以STL容器内存储的元素必须能够被拷贝(必须提供拷贝构造函数)。

除了queue和stack外,每个容器都提供可返回迭代器的函数,运用返回的迭代器就可以访问元素。

通常STL不会丢出异常,要求使用者确保传入正确的参数。


容器的共通能力:

每个容器都提供了一个默认构造函数与一个默认拷贝构造函数。如果已有容器vecIntA,

vector<int>vecIntB(vecIntA);//调用拷贝构造函数


各个容器的使用时机:


vector使用场景:比如软件历史操作记录的存储,我们经常要查看历史记录,比如上一次的记录,上上次的记录,但却不会去删除记录,因为记录是事实的描述。

deque的使用场景:比如排队购票系统,对排队者的存储可以采用deque,支持头端的快速移除,尾部的快速添加。若用vector实现类似功能,则会移动大量数据,速度慢。

vector与deque的比较:

1.vector.at()比deque.at()的效率高

2.如果有大量释放操作的话,vector花时间更少

3.deque支持头部的快速插入和快速移除


list的使用场景:比如公交车乘客的存储,随时都有乘车上下车,支持频繁的不确定位置元素的移除插入。

set的使用场景:比如对手机游戏的个人得分记录的存储,存储要求从高分到低分的顺序排列。


map的使用场景:比如按ID号存储十万个用户,想要快速通过ID查找对应的用户,这时二叉树的查找效率就体现出来了。如果是vector容器,最坏情况下可能遍历完整个容器才能找到该用户。


常用算法(Algorithm)的用法介绍

算法部分主要由头文件<algorithm>,<numeric>和<functional>组成。

<algorithm>是所有STL文件中最大的一个,其中常用到的功能范围涉及到比较,交换,查找,遍历操作,复制,修改,反转,排序,合并等。

<numeric>体积很小,只包括几个在序列上面进行简单数学运算的模板函数,包括加法和乘法在序列上的一些操作。

<functional>中则定义了一些模板类,用以声明函数对象。

STL提供了大量实现算法的模板函数,可以大大简化代码,提升效率。


使用前准备

#include <algorithm>

#include <numeric>

#include <functional>

using namespace std;


常用的查找算法:

adjacent_find(),binary_search(),count(),count_if(),equal_range(),find_if()

常见的排序算法:

merge(),sort(),random_shuffle()(shuffle是洗牌的意思),reverse()

常见的拷贝和替换算法:

copy(),replace(),replace_if(),swap()

常见的算术和生成算法:

accumulate()(accumulate是求和的意思),fill()

常见的集合算法;

set_union(),set_intersection(),set_difference()

常见的遍历算法:

for_each(),transform()(transform是变换的意思)


常见的adjacent_find():在iterator对标识元素范围内,查找一对相邻重复元素,找到则返回指向这对元素的第一个元素的迭代器。否则返回past-the-end

vecInt包含1,2,2,4,5

vector<int>::iterator it=adjacent_find(vecInt.begin(),vecInt.end());

此时*it==2

binary_search:在有序序列中查找value,找到返回true。注意:在无序序列中不可使用

count:利用等于操作符,把标志范围内的元素与输入值比较,返回相等的个数。

count_if:利用输入的函数,对标志范围内的元素进行比较操作,返回结果为true的个数

例如vecInt有1,3,5,7,9要求出大于等于3的元素个数:

先定义比较函数:

bool GreaterThree(int iNmu)

{

    if(iNum>=3)

    {

        return true;

    }

    else

    {

        return false;

    }

}

int iCount=count_if(vecInt.begin(),vecInt.end(),GreaterThree);

此时,iCount==4

equal_range:返回一对iterator,第一个表示lower_bound,第二个表示upper_bound.

find:利用底层元素的等于操作符,对指定范围内的元素与输入值进行比较,当匹配时,结束搜索,返回该元素的迭代器。

如查找5

find(vec,begin(),vec.end(),5);


find_if:使用输入的函数代替等于操作符,执行find,返回被找到的元素的迭代器

find_if(vec.begin(),vec.end(),GreaterThree);


常用的排序算法:

merge:合并两个有序序列,存放到另外一个序列。

例如vecIntA包含1,3,5,7,9,vecIntB包含2,4,6,8

vecIntC.resize(9);//扩大容量

merge(vecIntA.begin(),vecIntA.end(),vecIntB.begin(),vecIntB.end(),vecIntC.begin());

此时,vecIntC就存放了按顺序的1,2,3,4,5,6,7,8,9


sort:以默认升序的方式重新排列指定范围内的元素,若要改排序规则,可以输入比较函数。

vec包含2,1,4,3,6,5

sort(vec.begin(),vec.end());

此时,vec包含了1,2,3,4,5,6

如果vector<T>,T是自定义类型,则要提供T类型的比较函数。


random_shuffle:对指定范围内的元素随机调整次序(随机洗牌)

reverse:对指定范围内元素重新反序排列。


拷贝和替换的算法:

copy:复制序列

例如vecA包含1,3,5,7,9

vecB.resize(5);

copy(vecA.begin(),vecA.end(),vecB.begin());

此时,vecB也包含了1,3,5,7,9


replace(beg,end,oldValue,newValue):将指定范围内的所有等于oldValue的元素替换成newValue。


replace_if(beg,end,GreaterThree,newValue);将指定范围内所有符合GreaterThree条件(自定义条件)结果为true的元素用新值替换。

swap:交换两个容器的元素。


算术:

accumulate(beg,end,value):对指定范围内的元素求和,然后结果再加上一个由val指定的初始值。

fill(beg,end,value)将value赋给标志范围内的所有元素。


常用的集合算法:(与或非逻辑)

set_union(A.begin(),A.end(),B.begin(),B.end(),C.begin()):构造一个有序序列,包含两个有序序列的并集。

set_intersection(A.begin(),A.end(),B.begin(),B.end(),C.begin()):构造一个有序序列,包含两个有序序列的交集。

set_difference(A.begin(),A.end(),B.begin(),B.end(),C.begin()):构造一个有序序列,该序列保留第一个有序序列存在而第二个有序序列不存在的元素。


常用的遍历算法:

for_each:用指定函数依次对指定范围内所有的元素进行迭代访问,该函数不得修改序列中的元素。

定义show函数:

void show(const int &iTem)

{

    cout<<iTem;

}

for_each(vec.begin(),vec.end(),show());

以上则打印出vec的所有元素。

transform:与for_each类似,遍历所有元素,但可对容器的元素进行修改。









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值