C++学习笔记(Day17 函数适配器 算法)

函数适配器

  • 绑定适配器:bind1st、bind2nd

    • 将n元函数对象的指定参数绑定为一个常数,得到n-1元函数对象

  • 组合适配器:not1、not2

    • 将指定谓词的结果取反

  • 函数指针适配器:ptr_fun

    • 将一般函数指针转换为函数对象,使之能够作为其它函数适配器的输入。

    • 在进行参数绑定或其他转换的时候,通常需要函数对象的类型信息,例如bind1st和bind2nd要求函数对象必须继承于binary_function类型。但如果传入的是函数指针形式的函数对象,则无法获得函数对象的类型信息。

  • 成员函数适配器:ptrfun、ptrfun_ref

    • 对成员函数指针使用,把n元成员函数适配为n + 1元函数对象,该函数对象的第一个参数为调用该成员函数时的目的对象

    • 也就是需要将“object->method()”转为“method(object)”形式。将“object->method(arg1)”转为二元函数“method(object, arg1)”。

绑定适配器

  • binder2nd的实例构造通常比较冗长,bind2nd函数用于辅助构造binder2nd,产生它的一个实例。

  • binder1st和bind1st,将一个具体值绑定到二元函数的第一个参数。

例10-17:函数适配器实例——找到数组中第一个大于40的元素

//10_17.cpp
#include <functional>
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

int main() {
    int intArr[] = { 30, 90, 10, 40, 70, 50, 20, 80 };
    const int N = sizeof(intArr) / sizeof(int);
    vector<int> a(intArr, intArr + N);
    vector<int>::iterator p = find_if(a.begin(), a.end(), bind2nd(greater<int>(), 40));
    if (p == a.end())
        cout << "no element greater than 40" << endl;
    else
        cout << "first element greater than 40 is: " << *p << endl;
    return 0;
}

注:
find_if算法在STL中的原型声明为:
template<class InputIterator, class UnaryPredicate>
InputIterator find_if(InputIterator first, InputIterator last, UnaryPredicate pred);
它的功能是查找数组[first, last)区间中第一个pred(x)为真的元素。

算法

STL算法特点

  • STL算法本身是一种函数模版

    • 通过迭代器获得输入数据

    • 通过函数对象对数据进行处理

    • 通过迭代器将结果输出

  • STL算法是通用的,独立于具体的数据类型、容器类型

STL算法分类

  • 不可变序列算法

  • 可变序列算法

  • 排序和搜索算法

  • 数值算法

不可变序列算法

  • 不直接修改所操作的容器内容的算法

  • 用于查找指定元素、比较两个序列是否相等、对元素进行计数等

  • 例:

    template<class InputIterator, class UnaryPredicate>
    InputIterator find_if(InputIterator first, InputIterator last, UnaryPredicate pred);

    查找[first, last)区间内pred(x)为真的首个元素

可变序列算法

  • 可以修改它们所操作的容器对象

  • 包括对序列进行复制、删除、替换、倒序、旋转、交换、分割、去重、填充、洗牌的算法及生成一个序列的算法

  • 例:

    template<class ForwardIterator, class T>
    InputIterator find_if(ForwardIterator first, ForwardIterator last, const T& x);

    将[first, last)区间内的元素全部改写为x。

排序和搜索算法

  • 对序列进行排序

  • 对两有序序列进行合并

  • 对有序序列进行搜索

  • 有序序列的集合操作

  • 堆算法

  • 例:

    template <class RandomAccessIterator , class UnaryPredicate>
    void sort(RandomAccessIterator first, RandomAccessIterator last, UnaryPredicate comp);

    以函数对象comp为“<”,对 [first, last)区间内的数据进行排序

数值算法

  • 求序列中元素的“和”、部分“和”、相邻元素的“差”或两序列的内积

  • 求“和”的“+”、求“差”的“-”以及求内积的“+”和“·”都可由函数对象指定

  • 例:

    template<class InputIterator, class OutputIterator, class BinaryFunction>
    OutputIterator partial_sum(InputIterator first, InputIterator last, OutputIterator result, BinaryFunction op);

    对[first, last)内的元素求部分“和”(所谓部分“和”,是一个长度与输入序列相同的序列,其第n项为输入序列前n个元素的“和”),以函数对象op为“+”运算符,结果通过result输出,返回的迭代器指向输出序列最后一个元素的下一个元素

算法应用举例

  • 例10-20——例10-23演示了几类算法的应用。

  • 详见教材第10章

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值