容器算法

<algorithm>c++自带的容器算法,提供一系列实用的算法。在谈到容器算法,我们大概率会用到谓词predicate,谓词返回的类型是布尔类型(bool)可以是lambda表达式、函数对象以及其它可调用的对象。

查找

  1. find()查找元素

    find接受三个参数,第三个参数是值类型,setmap自带count函数也能实现这样的功能,返回值0表示不存在。为了方便本次连带find_iffind_if_notfind_first_offind_endadjacent_find一起举例。

    vector<int> a{1, 1, 2, 3, 4, 4, 5};
    vector<int> b{5, 6, 6};
    find(a.begin(), a.end(), 3); // 返回的是迭代器,未查找到返回a.end()
    find_if(a.begin(), a.end(), [](auto x){return x != 3;}); //接受一个一元谓词,找到第一个满足条件的元素
    find_if_not(a.begin(), a.end(), [](auto x){return x != 3;}); //接受一个一元谓词,找到第一个不满足条件的元素 // find_first_of找到存在于第一个范围的第二个范围中的第一个元素(可能并不是第二个范围第一个元素),返回迭代器,也支持一个二元谓词。
    vector<int> a{1, 1, 2, 3, 4, 4, 5};
    vector<int> b{6, 5, 6};
    auto it = find_first_of(a.begin(), a.end(), b.begin(), b.end());
    cout << *it << endl; // 返回5 // find_end找到最后一个匹配子序列的位置,返回最后一个子序列开始的迭代器,也支持一个二元谓词
    vector<int> a{1, 1, 2, 3, 1, 4, 1, 2};
    vector<int> b{1, 2};
    auto it = find_end(a.begin(), a.end(), b.begin(), b.end());
    cout << distance(a.begin(), it) << endl; // 6指向第7个元素 // adjcent_find找到两个值邻近的元素,返回指向找到的第一个元素的迭代器,接受一个二元谓词
    vector<int> a{1, 1, 2, 3, 4, 1, 2};
    vector<int> b{1, 2};
    auto it = adjacent_find(a.begin(), a.end());
    auto it = adjacent_find(a.begin(), a.end(),
    [](auto a, auto b)->bool{return a + b = 10;});
    cout << *it << endl;

去重

  1. unique(nums.begin(), nums.end())除掉连续相同的值

    unique函数的作用是删除掉的连续的相同的值,unique还支持传入二元谓词(可以理解为一个参数的函数),会返回一个迭代器it,但是并不是end(),中间是未指定的值(访问可能会产生未定义行为)。注意不要用set,返回的都是常量迭代器是无法改变的,其指向的元素无法改变。

    // 无谓词写法
    vector<int> a{1, 1, 2, 3, 4, 4, 5};
    auto it = unique(a.begin(), a.end()); // 此时a为{1, 2, 3, 4, 5}
    for_each(a.begin(), a.end(), [](auto it){cout << it << endl;}); // 输出为{1, 2, 3, 4, 5, 4, 5}
    for_each(a.begin(), it, [](auto it){cout << it << endl;}); // 输出为{1, 2, 3, 4, 5}
    // 有二元谓词
    vector<int> a{1, 1, 2, 3, 4, 4, 5};
    auto it = unique(a.begin(),
    a.end(), [](auto a, auto b) -> bool{return a != b;}); // 此时a为{1, 2, 3, 4, 5},lambda表达式作为一个二元谓词,每次从数组中取两个严肃进行判断,然后删除不相等的元素。
    for_each(a.begin(), a.end(), [](auto it) -> int{cout << it << endl;}); // Error,这是因为unique将返回的迭代器到之后的end()迭代器指向的值删除了,但是空间还在。此时访问,会发生未定义行为。
    for_each(a.begin(), it, [](auto xs){cout << xs << endl;}); // 1,1
    cout << distance(a.begin(), a.end()) << endl; // 7,distance求算距离是7
  2. unique_copy()除掉连续相同的值并复制到目标容器

    注意,unique_copy并不进行内存分配,只是赋值给另一个容器,如果访问未分配内存的容器,那么会产生未定义行为。同样,也支持二元谓词,通过二元谓词判定移除连续值。

    vector<int> a{1, 1, 2, 3, 4, 4, 5};
    vector<int> b(7, 0);
    auto it = unique_copy(a.begin(), a.end(), b.begin());
    for_each(b.begin(), it, [](auto xs){cout << xs << endl;}); // out: 1 2 3 4 5 // 二元谓词, 一般不要使用二元谓词与数字直接进行比较,可以使用remove实现
    auto it = unique_copy(a.begin(),
    a.end(), b.begin(), [x](auto a, auto b)
    -> bool{return a == 3;});
    for_each(b.begin(), it, [](auto xs){cout << xs << endl;}); // out: 1 1 2 3,解释:值等于3才会进行unique_copy auto it = unique_copy(a.begin(),
    a.end(), b.begin(), [x](auto a, auto b)
    -> bool{return a == b;});
    for_each(b.begin(), it, [](auto xs){cout << xs << endl;}); // out: 1 2 3 4 5,解释:值等于3才会进行unique_copy

排序

  1. sort()对容器进行排序

    sort用于实现容器元素的排序,sort也同样接受二元谓词

    sort(a.begin(), a.end());
    sort(a.begin(), a.end(), greater<>()); // 使用库中自带的greater\less对象

迭代器差值

  1. distance()求迭代之间距离

    distance用于求算两个迭代器之间的差值,只用于同一容器, setmapvector都可以用。

    distance(c.begin(), c.end());

遍历容器

  1. for_each()for_each_n遍历容器每个元素并执行函数规定的操作,第三个参数是一个函数。如果要对迭代器指向的元素修改,那么set就是不可以的,因为set返回的是常量迭代器。

    array<int, 5> a{1, 2, 3, 4, 5};
    for_each(a.begin(), a.end(), [](int& x){cout<< x; x *= 2;}); // 此时元素值会发生改变,因为捕获的是引用。
    for_each(a.begin(), a.end(), [](auto x) -> void{x *= 2; cout << x;}); // 此时元素值不会发生改变,捕获的是值,会变为副本。
    for_each_n(a.begin, 5, [](auto x) -> void{x *= 2; cout << x;}); // 第二个参数指定操作的数量n, 对n个元素进行操作。

复制元素

  1. copy()能够将容器中的元素复制到输出迭代器之后out iterator

    vector<vector<int>> sx(1);
    copy(sx.begin(), sx.end() , sx.begin()); // 可以将[begin, end)之间的元素复制到从begin()开始的位置。 // 一个有意思的做法是使用back_inserter指明要进行尾插法,某些支持双向插入的容器也可以转变为尾插方法,省去了一些需要选择插入函数的麻烦。
    // set、map类红黑树容器不存在后插方法,无法进行此类调用,注意
    copy(sx.begin(), sx.end() , back_inserter(sx)); vector<int> a{1, 2, 3};
    set<int> s;
    copy(a.begin(), a.end() , back_inserter(s)); // Error // 接下来我们考虑一个向vector<vector<int>>复制的问题
    vector<vector<int>> v(1); // 此时外部vector容量为1,size也是1。说明内部存在一个vector容器元素,但是此时vector[0]的size和capacity都是0,是一个空容器。
    copy(v.begin(), v.end(), back_inserter(v)); // 此时内部空容器是2个
  2. copy_backward()能够将容器中元素复制到输出迭代器之前。

    map、set类也不支持。这个容器算法会覆盖掉输出迭代器之前的元素

    vector<int> a{1, 2, 3, 4, 5, 6};
    set<int> s;
    copy_backward(a.begin(), a.end() , s); // Error
    copy_backward(a.begin(), a.begin() + 3, a.end()); // OK a{1, 2, 3, 1, 2, 3}
    copy_backward(a.begin(), a.begin() + 3, a.begin()); // OK,但是数组不会发生任何改变,相当于复制到begin()迭代器之前没有意义。

C++容器算法的更多相关文章

  1. 【足迹C++primer】35、特定容器算法

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/cutter_point/article/details/33732681 特定容器算法 lst.me ...

  2. STL的容器算法迭代器的设计理念

    1) STL的容器通过类模板技术,实现数据类型和容器模型的分离. 2) STL的迭代器技术实现了遍历容器的统一方法:也为STL的算法提供了统一性. 3) STL的函数对象实现了自定义数据类型的算法运算 ...

  3. c++容器 算法 迭代

    #include <iostream> #include <vector> using namespace std; int main() { // 创建一个向量存储 int ...

  4. C++容器和算法

    转自:http://www.cnblogs.com/haiyupeter/archive/2012/07/29/2613145.html 容器:某一类型数据的集合. C++标准顺序容器包括:vecto ...

  5. 4_STL设计理念_算法

    STL算法,容器,迭代器的设计理念1.STL容器通过 类模板 技术,实现 数据类型 和 容器模型的分离:2.迭代器技术 实现了 遍历和操作容器的统一方法3.STL算法设计理念:通过预定义的函数对象和函 ...

  6. C++ Primer :第十章 :泛型算法之再探迭代器以及其他算法

    除了为每个容器定义的迭代器之外,标准库在头文件<iterator>还定义了额外集中迭代器, 包括: 插入迭代器,这些迭代器被绑定到一个容器上,可以向容器插入元素. 流迭代器,    这些迭 ...

  7. C++ Primer : 第十章 : 泛型算法 之 只读、写和排序算法

    大多数算法都定义在<algorithm>头文件里,而标准库还在头文件<numeric>里定义了一组数值泛型算法,比如accumulate. ●  find算法,算法接受一对迭代 ...

  8. C++标准库之泛型算法

    本文中算法都是指泛型算法. 基本要点: 1)算法使用迭代器进行操作. 2)不依赖容器,但容器希望使用算法,就必须提供接口. 3)通用算法永远不会执行容器操作.操作仅指:更改容器大小的操作.但,容器内部 ...

  9. C++ STL常用容器浅析

    首先要理解什么是容器,在C++中容器被定义为:在数据存储上,有一种对象类型,它可以持有其它对象或指向其它对象的指针,这种对象类型就叫做容器.简单来说 容器就是包含其他类的对象们的对象,当然这种(容器) ...

  10. c++常用小算法

    这篇文章列出了一些简单常用的C++容器算法,C++标准库中事实上提供了很多的算法并且有详细的介绍.如果需要详细的了解这些算法可以 参考C++在线参考手册 algrithm . 1 排序 在 #incl ...

随机推荐

  1. 高通与At指令:ATFWD解析

    背景 本章的内容是适用于AP侧AT指令开发调试的有关人员. 主要是介绍高通实现的ATFWD框架.在这需要说明一下的是,或许你对AT Command很了解了,但是却貌似都不知道ATFWD,这很正常,严格 ...

  2. 嵌入式ARM端测试手册——全志T3+Logos FPGA开发板(上)

    前 言 本指导文档适用开发环境: Windows开发环境:Windows 7 64bit.Windows 10 64bit Linux开发环境:Ubuntu18.04.4 64bit 虚拟机:VMwa ...

  3. 全国产!瑞芯微RK3568J/RK3568B2工业核心板规格书

    核心板简介 创龙科技SOM-TL3568是一款基于瑞芯微RK3568J/RK3568B2处理器设计的四核ARM Cortex-A55全国产工业核心板,每核主频高达1.8GHz/2.0GHz.核心板CP ...

  4. HTTP 和 HTTPS,为什么HTTPS安全?

    HTTP协议通常承载与 TCP协议之上,在HTTP和TCP之间添加一个安全协议层(SSL或TSL),这个时候,就成了我们常说的HTTPS 默认HTTP的端口号为80,HTTPS的端口号为443 因为网 ...

  5. SpringBoot Maven查看依赖树

    dependency:tree -f pom.xml

  6. PixiJS源码分析系列: 第一章 从最简单的例子入手

    从最简单的例子入手分析 PixiJS 源码 我一般是以使用角度作为切入点查看分析源码,例子中用到什么类,什么方法,再入源码. 高屋建瓴的角度咱也做不到啊,毕竟水平有限 pixijs 的源码之前折腾了半 ...

  7. thinkphp模型hasOne、hasMany、belongsTo详解

    在ThinkPHP框架中,hasOne.hasMany和belongsTo是用于定义模型间一对多(1:n).一对一(1:1)和多对一(n:1)关联关系的方法.以下是一些简单的示例来解释这些关系: 1. ...

  8. tp 模型hasOne、hasMany、belongsTo详解

    首先,这3个的大致中文意思:hasOne:有一个,加上主谓语应该是 ,A 有一个 BhasMany:有很多,A 有很多 BbelongsTo:属于, A 属于 B这里我们准备3张表来理解他们的关系:u ...

  9. oeasy教您玩转vim - 4 - # 深入帮助

    深入帮助 回忆上节课内容 上次制作了 oeasy.txt 用 vim oeasy.txt 打开了文件 :f[ile] 查询了当前文件 的信息 从 正常模式或命令模式(Normal mode) 切换到 ...

  10. 欧拉系统初体验与编译安装FFmpeg的过程记录

    目录 源起 1. 系统下载 2. 系统安装 2.1 磁盘分区 2.2 软件数量 2.3 安装完毕 3.进入系统 4.安装FFmpeg 4.1 下载FFmpeg 4.2 解压程序 4.3 检查环境 4. ...