第十一章:泛型算法与Lambda表达式(一)

本文探讨了C++中泛型算法的原理,如何通过迭代器支持多种类型,以及C++17/20引入的策略控制执行逻辑。重点讲解了算法分类、迭代器种类和策略如顺序执行、并发等的应用实例。

泛型算法

泛型算法是可以支持多种类型的算法,这里主要讨论C++标准库中定义的算法,包括

  • algorithm
  • numeric
  • ranges

这里出现了一个问题,那就是为什么要引入泛型算法而不采用方法的形式,主要原因有以下两点

这里的方法指的是类的成员函数

  • 内建数据类型不支持方法
  • 泛型算法内部的计算逻辑一般来说是存在相似性的,可以避免在方法中重复实现相同的逻辑

    这里的相似性一般使用模版来实现

那么泛型算法如何实现支持多种类型呢?C++给出的办法是使用迭代器来作为算法与数据之间的桥梁,比如

    std::vector<int>x(100);
    std::sort(std::begin(x),std::end(x));

泛型算法通常来说都不复杂,但拥有足够好的优化,主要体现在:速度足够快,对于异常输入的处理足够鲁棒

在C++中,一些算法与方法同名,实现的功能类似,此时我们建议调用方法而不是算法,比如std::find VS std::map::find

这里的std::find使用的是线性查找,而std::map::find利用了红黑树的排序性质,实现了类似二分的查找

通常来说类的成员方法的性能要优于同名的泛型算法

这里我们将泛型算法大致分为三类

  • 读算法:给定一个迭代区间,读取其中的元素并进行计算,比如
    1. accumulate:累加,在C++20以后可以自定义操作
    2. find:查找
    3. count:计数
  • 写算法:向一个迭代区间中写入元素
    1. 单纯写操作:
      • fill:给定一个区间,将区间中的元素全部使用给定值填充
      • fill_n:给定区间开头和要填充的个数,使用给定值填充区间开头之后指定个数的元素
    2. 读+写操作
      • transform:遍历输入区间的每一个元素,对元素进行变换并写入到输出区间中
      • copy:遍历输入区间的每一个元素,将输入区间的元素拷贝到输出区间中

    注意fill_ntransformcopy都不会给定输出区间或者填充区间的结尾,所以一定要确保目标区间足够大,否则会产生未定义的行为

  • 排序算法:改变输入区间中元素的顺序,缺省情况下从小到大,元素要支持使用<进行排序

    可以自定义排序方法

    • sort:对区间内快排
    • unique:对有序区间内的元素进行去重

    注意unique只是将不重复的元素放到了区间开头的部分,返回一个指向不重复元素区间下一个位置的迭代器,我们后续需要对后面的元素进行删除才能得到真正的有序不重复区间

我们可以看到以上的泛型算法基本上都是基于迭代器来实现的,C++中的迭代器分为以下几类:

  • 输入迭代器:可读、可递增,典型的应用为find算法
  • 输出迭代器:可写、可递增,典型的应用为copy算法
  • 前向迭代器,可读写、可递增,典型的应用为replace算法
  • 双向迭代器、可读写、可递增递减,典型应用为reverse算法
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值