C++ 学习笔记之(10) - 泛型算法和迭代器

本文是C++学习笔记的第十篇,主要介绍了泛型算法和迭代器的概念与应用。泛型算法不依赖于特定容器,而是通过迭代器对元素进行操作。文章详细讲解了只读算法、写容器元素的算法、重排元素的算法,以及如何定制操作,如向算法传递函数、使用表达式和参数绑定。同时,文中探讨了不同类型的迭代器,包括插入迭代器、反向迭代器和流迭代器,并分析了各种迭代器的特性及适用场景。
摘要由CSDN通过智能技术生成

C++ 学习笔记之(10) - 泛型算法和迭代器

标准库容器定义的操作结合非常小,为了实现更丰富的功能,标准库定义了一组反省算法。

概述

大多数算法定义在头文件algorithm中,头文件numeric中定义了一组数值泛型算法

  • 迭代器令算法不依赖于容器,但依赖于元素类型的操作,比如元素类型的==运算符
  • 泛型算法本身不会执行容器的操作,他们只会运行于迭代器之上,故算法永远不会改变底层容器的大小

初识泛型算法

除了少数列外,标准库算法都对一个范围内的元素进行操作。此元素范围被称为输入范围。接受输入范围的算法总是使用前两个参数表示此范围,两个参数分别是指向要处理的第一个元素和尾元素之后位置的迭代器。

只读算法

某些算法只读取输入范围内的元素,而从不改变元素

  • accumulate :定义在头文件numeric中,求和算法, 第三个参数的类型决定了函数使用那个加法运算符以及返回值的类型。

    // 对 vec 中的元素求和,初识为 0 
    int sum = accumulate(vec.cbegin(), vec.cend(), 0);
    // 链接 v 中所有 string 元素
    string num = accumulate(v.cbegin(), v.cend(), string(""));
  • equal:确定两个序列是否保存相同的值

    // roster2 中的元素数目应该至少与 roster1 一样多
    equal(roster1.cbegin(), roster1.cend(), roster2.cbegin());

    那些只接受一个单一迭代器来表示第二个序列的算法,都假定第二个序列至少与第一个序列一样长

写容器元素的算法

某些算法将新值赋予序列中的元素

  • 算法并不会执行容器操作,故不可能改变容器大小

  • 一些算法从两个序列中读取元素,构成这两个序列的元素可以来自于不同的容器类型

  • 若第二个序列是第一个序列的子集,则程序会产生严重错误

  • 插入迭代器(insert iterator):一种向容器中添加元素的迭代器

  • 拷贝算法:另一个向目的位置迭代器指向的输出序列中的元素写入数据的算法

    // 把 a1 的内容拷贝到 a2, ret 指向拷贝到 a2 的尾元素之后的位置
    auto ret = copy(begin(a1), end(a1), a2);
    // 将所有值为 0 的元素改为 42
    replace(ilst.begin(), ilst.end(), 0, 42);

重排容器元素的算法

某些算法会重排容器中元素的顺序, 比如sort

  • 举例:消除文本中重复单词
    • 首先将vector排序,使用sort
    • 然后使用unique算法重排vector,使得不重复的单词出现在vector前面,返回指向不重复值范围末尾的迭代器
    • 使用容器操作真正删除元素
  • 标准库算法对迭代器而不是容器操作,故算法不能(直接)添加或删除元素

定制操作

很多算法会比较输入序列中的元素,默认使用元素类型的<==运算符,也可以使用自定义操作代替

向算法传递函数

  • 谓词:可调用的表达式,返回结果是一个能用作条件的值,接受谓词参数的算法对输入序列中的元素调用谓词

    • 一元谓词:接受单一参数
    • 二元谓词:接受两个参数
    // 比较函数,用来按长度排序单词
    bool isShorter(const string &s1, const string &s2)
    {
      return s1.size() < s2.size();
    }
    // 按长度由断至长排序 words
    sort(words.begin(), words.end(), isShorter);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值