zoukankan      html  css  js  c++  java
  • 10泛型算法

    标准库并未给每个容器都添加大量功能,而是提供了一组标准算法,这些算法中的大多数都独立于任何特定的容器。这些算法是通用的(generic 或称为泛型的):它们可以用于不同类型的容器和不同类型的元素。

    泛型算法(generic algorithm)之所以称为算法,是因为它们实现了一些经典算法的公共接口,如排序或搜索;称他们是泛型的,是因为它们可以用于不同类型的元素和多种容器类型。

    三、lambda

    调用运算符:如果可以对其使用调用运算符,则称一个对象是可以被调用的。 目前用过的可调用对象:函数和指针

    [capture list](parameter list) ->return type {function body}

    capture list(捕获列表)是一个lambda所在函数中定义的局部变量的列表(通常为空),其他与普通函数一样。lambda必须使用尾置返回来指定返回类型。

    lambda不能有默认参数,所以lambda调用的实参数目必须与形参数目相等。

    [](const string &a,const string b)
        {return a.sie() < b.size();}
    

     空捕获列表表明lambda不使用它所在函数中的任何局部变量。

    stable_sort(words.begin(),words.end(), [](const string &a,const string b){return a.sie() < b.size();));

    当stable_sort需要比较两个元素时,它就会调用lambda表达式。

    lambda通过将局部变量包含在其捕获列表中,来指出将会使用这些变量。一个lambda只有在其捕获列表中捕获一个它所在函数中的局部变量,才能在函数中使用该变量。

    [sz](const string &a)
        {return a.size() >= sz;}
    
    auto wc = find_if(words.begin(),words.end(),[sz](const string &a){return a.size() >= sz});
    

     指向第一个长度大于给定参数sz的元素。如果不存在,则返回words.end()的一个拷贝。

    例 1.接受两个int,返回它们的和。

    auto sum = [](int a,int b) {return a + b};

    2.捕获所在函数的int,并接受一个int参数。返回捕获int和int参数的和。

    void add(int a){
        auto sum =[a](int b ) {return a + b };
    }
    

     3.1 lambda捕获与返回

    当向函数传递一个lambda时,同时定义了一个新类型与该类型的对象:传递的参数就是此编译器生成的类类型的未命名对象。

    类似参数传递,变量的捕获方式也可以是值或者引用。

    值捕获:在lambda创建时就拷贝v1的值,后面v1的值改变不影响值捕获的变量。 引用捕获:在lambda函数体内使用此变量时,实际上使用的是引用所绑定的对象。 当以引用方式捕获一个变量时,必须保证在lambda执行时变量时存在的。

    混合使用显式捕获和隐式捕获:

    &告诉编译器捕获引用方式; =告诉编译器采用值捕获方丝滑。

    可变lambda

    对于值捕获,参数列表加上:mutabl

    auto f =[v1] () mutable {return ++v1};

    一个引用捕获的变量能否修改取决于引用指向的变量时const 还是非const类型。

    指定lambda返回类型

    当需要为lambda指定返回类型时,必须使用尾置类型。

    [](int i) -> int {if (i < 0)  return -i; else return i;}

    四、迭代器

    插入迭代器

     标准库算法为了保证通用性,并不直接操作容器,而是通过迭代器来访问容器元素,算法不具备直接向容器插入元素的能力,而插入器正式帮助算法实现向容器插入元素的能力。有三种类型,区别在于元素插入位置不同。

    • back_inserter
    1. 原理:创建一个使用push_back的迭代器。调用push_back.
    2. 功能:在容器的尾端插入元素。
    3. 限制:只有提供了push_back()成员函数的容器中,back_inserter才能派上用场。
    4. 适用:vector deque lis
    • front_inserter:
    1. 原理:创建一个使用push_front的迭代器。调用push_front.
    2. 功能:在容器前端插入元素
    3. 限制:只有提供了push_front()成员函数的容器中,form_Inserter才能派上用场。
    4. 适用:deque list
    • inserter
    1. 原理:创建一个使用insert的迭代器。此函数接受第二个参数,这个参数必须是一个指向给定容器的迭代器。元素将被插入到给定迭代器所表示的元素之前。
    2. 功能:在容器的指定位置插入元素。
    3. 限制:只有提供了inset()成员函数的容器中,inserter才能派上用场,所有STL容器都提供了inset()函数。
    4. 适用:所有STL容器。

    iostream迭代器

    通过流迭代器,我们可以用泛型算法从流对象读取数据以及向其写入数据。
    istream_iterator:读取输入流

    ostream_iterator:向一个输出流写数据。

    istream_iterator<int> in_iter(cin);//从cin读取int
    istream_iterator<int>eof; //isteram尾后迭代器
    while(in_iter != eof)
        vec.push_back(*in_iter++);

    对于一个绑定到流的迭代器,一旦关联的流遇到文件尾或遇到IO错误,迭代器的值就与尾后迭代器相等。

    ostream_iterator

    ostream_iterator(T) out(os);    //out将类型为T的值写入到输出流os中
    ostream_iterator(T) out(os,d)//out将类型为T值写入到输出流os中,每个值后面都输出一个d,d指向一个空字符结尾的字符数组。
    void change(vector<int>&vec) {
        ostream_iterator<int> out_iter(cout, "danliu");
        for (auto e : vec)
            *out_iter++ = e; //赋值语句将e写入到cout
        cout << endl;
    }

    以下代码也能用来打印容器

        ostream_iterator<int>out_iter(cout," ");
        copy(vec.begin(),vec.end(),outiter);

    五、泛型算法结构

    算法要求的迭代器操作可以分为5个迭代器类别(iterator category),每个算法都会对它的每个迭代器参数指明需要提供哪类迭代器。

    • Input iterator(输入迭代器):只读,不写,单遍扫描,只能递增;
    • Output iterator(输出迭代器):只写,不读,单遍扫描,只能递增;
    • Forward iterator (前向迭代器):可读写,多遍扫描,只能递增;
    • Bidirectional iterator(双向迭代器):可读写,多遍扫描,可递增递减;
    • Random Access iterator(随机访问迭代器):可读写,多遍扫描,支持全部迭代器运算;
    陈小洁的三只猫
  • 相关阅读:
    python3编写网络爬虫18-代理池的维护
    python3编写网络爬虫17-验证码识别
    python3编写网络爬虫16-使用selenium 爬取淘宝商品信息
    python3编写网络爬虫15-Splash的使用
    python3编写网络爬虫14-动态渲染页面爬取
    LeetCode959 由斜杠划分区域(Java并查集)
    编译原理--语法分析之LR分析法的简单实现
    VsCode背景图片设置
    编译原理--基于Lex的词法分析器实验
    HDFS常用的shell命令
  • 原文地址:https://www.cnblogs.com/ccpang/p/11303839.html
Copyright © 2011-2022 走看看