c++ primer第10章

来源:互联网 发布:asap2020软件 64bit 编辑:程序博客网 时间:2024/06/05 17:57

1 概述

    标准库没有给每个容器提供大量的功能,而是提供了一组算法,这些算法大部分独立于特定的容器。这些算法是通用的:他们可以用于不同类型的容器和不同类型的元素。

    泛型算法:一些经典算法的公共接口,用于不同类型元素、多种容器类型的排序、搜索。

头文件:algorithm

    这些算法一般,遍历由两个迭代器指定的一个元素范围来操作:

               auto result = find(vec.cbegin(),vec.cend(),42);

算法不会影响容器的大小,不会删除、添加元素,及算法不能执行容器操作;

2 初识泛型算法

2.1 accumulate()求和:

计算两个迭代器之间元素的和,第三个参数是初始值;定义的“+”运算的类型,都可以使用accumulate函数;

//算术求和

vector <int> venc;

int sum = accumulate(venc.cbedin(),venc.cend(),0);


//连接字符串

vector <string> v;

string sum = accumulate<v.cbegin(),v.cend(),string(" ") );

2.2 equal() 求等长类型相等否

equal(roster1.cbegin(), roster1.cend(),roster2.cbegin() );

roster1.cbegin(), roster1.cend(): 表示一个序列;

roster2.cbegin():第二个序列的首元素;


注意:

1 两个序列类型可以不一样,只要能用 == 比较就行;

2 算法假设两个序列一样长,在第二个序列中取出相同长度和一序列比较;

2.3 fill() 、fill_n()写容器

fill(venc.begin(),venc.end(),0 ); //将迭代器范围的值设为0;

fill_n(venc.begin(),venc.size(),0) //所有元素重置为0;

fill_n(dest.begin(), n ,val)  //dest的前n个重置为cal;


2.4 copy()拷贝算法


2.5 replace()替换序列某元素

replace(ilst.begin(),ilst.end(),0,42);   //将所有的 0 改为 42;

2.6 replace_copy()拷贝替换


2.7 sort()排序


sort(word.begin(),word.end()):范围内从小到大排序;

unique(word.begin(),word.end()):一般用于sort排序后的序列,将重复的元素排在后面,返回第一个重复元素所在位置;


sort(histVector.begin(), histVector.end(), greater<float>());

上述例子中系统自己为sort提供了less仿函数。在STL中还提供了其他仿函数,以下是仿函数列表:

名称

功能描述

equal_to

相等

not_equal_to

不相等

less

小于

greater

大于

less_equal

小于等于

greater_equal

大于等于





3 定制操作 

标准库,允许我们提供资金定义的操作;如sort()的方向排序;

3.1 向算法传递函数

sort的重载版本有第三个参数,其是谓词(只接受一个或者两个参数)


按照长度从短到长排序words

sort(words.begin(),words.end(),isShorter);

stable_wort(words.begin(),words.end(),isShorter);  //长度从短到长,相等大小的,按字母表顺序排;


elimDup(words);  //将words按字典排序,删除重复单词;

 //用partition()函数,第三个谓词参数为真的排在前面,为假的排在后面,返回第一个为假的

#include <iostream>#include <string>#include <vector>#include <algorithm>//! Predicateinlinebool isLongerThan5(const std::string &s){    return s.size() >= 5;}void partition_words(std::vector<std::string> &v){    auto iter_longerLast = std::partition(v.begin(), v.end(), isLongerThan5);    //! @note   the range to be printed not whole of the v, so can't use for range.    for(auto it = v.begin(); it != iter_longerLast; ++it)        std::cout << *it << " ";    std::cout << std::endl;}int main(){    std::vector<std::string> v{"a","as","aasss","aaaaassaa","aaaaaabba","aaa"};    partition_words(v);    return 0;}

3.2 lambda 表达式

可调用对象有:函数、指针、重载了函数调用运算符的类、lambda表达式;

lambda表达式,表示一个可调用的代码单元。

    与任何函数类似,一个lambda具有一个返回类型、一个参数列表、一个函数体;

    lambda可能定义在函数内部;


  1. [captures] (params) -> ret {Statments;}  


    注释:[capturne]方括号中的数是另外包含进去的可使用的数;

        

//sort()排序、enique()再排序、vs.erase()删除重复、stable_sort()大小字幕表排序、find_if()找到第一个大小为3的、for_each打印每个大于等于三的;

    auto wc = std::find_if(vs.begin(), vs.end(),[sz](string const& s){            return s.size() >= sz;    }); std::for_each(wc, vs.end(), [](const string &s){        std::cout << s << " ";    }); 

//找出vector<strig> 中,所有size()大于3的字符串,并输出,不可重复;

//

#include <iostream>#include <string>#include <vector>#include <algorithm>//! from ex 10.9void elimdups(std::vector<std::string> &vs){    std::sort(vs.begin(), vs.end());    auto new_end = std::unique(vs.begin(),vs.end());    vs.erase(new_end, vs.end());}//! ex10.18void biggies_partition(std::vector<std::string> &vs, std::size_t sz){    elimdups(vs);        auto pivot = partition(vs.begin(), vs.end(),[sz](const std::string &s){        return s.size() >= sz;}    );    for(auto it = vs.cbegin(); it != pivot; ++it)        std::cout << *it << " ";}//! ex10.19void biggies_stable_partition(std::vector<std::string> &vs, std::size_t sz){    elimdups(vs);        auto pivot = stable_partition(vs.begin(), vs.end(),[sz](const std::string& s){        return s.size() >= sz;    });    for(auto it = vs.cbegin(); it != pivot; ++it)        std::cout << *it << " ";}int main(){    //! ex10.18    std::vector<std::string> v{        "the", "quick", "red", "fox", "jumps", "over", "the", "slow", "red", "turtle"    };        std::cout << "ex10.18: ";    std::vector<std::string> v1(v);    biggies_partition(v1,4);    std::cout << std::endl;    //! ex10.19    std::cout << "ex10.19: ";    std::vector<std::string> v2(v);    biggies_stable_partition(v2,4);    std::cout << std::endl;    return 0;}

3.3 lambda值捕获:


#include <iostream>#include <string>#include <vector>#include <algorithm>using std::vector;using std::count_if;using std::string;//! Exercise 10.20std::size_t bigerThan6(vector<string> const& v){    return count_if(v.cbegin(), v.cend(), [](string const& s){        return s.size() > 6;    });}int main(){    //! ex10.20    vector<string> v{        "alan","moophy","1234567","1234567","1234567","1234567"    };    std::cout << "ex10.20: " << bigerThan6(v) << std::endl;    //! ex10.21    int i = 7;    auto check_and_decrement = [&i](){ return --i ? false : true; };    std::cout << "ex10.21: ";    while(!check_and_decrement())        std::cout << i << " ";    std::cout << i << std::endl;    return 0;}//! output  ://!//ex10.20: 4//ex10.21: 6 5 4 3 2 1 0


3.4 参数绑定


//统计长度大于等于6的个数

#include <iostream>#include <vector>#include <string>#include <algorithm>#include <functional>using std::string;using namespace std::placeholders;bool isBiggerThan6(const string &s, string::size_type sz){    return s.size() > sz;}int main(){    std::vector<string> authors{"Mooophy", "pezy", "Queequeg90", "shbling", "evan617"};    std::cout << count_if(authors.cbegin(), authors.cend(), bind(isBiggerThan6, _1, 6));}//  @Out//  4

4 再探迭代器



4.1 插入迭代器





  std::unique_copy(vec.begin(), vec.end(), back_inserter(lst)); //无重复的拷贝;

4.2 iostream迭代器

4.2.1 istream_iterator迭代器



stream_iterator<int> in_iter(cin); //

stream_iterator<int> eof;  //定义为空,从而可当作尾后迭代器来使用。




4.2.2 ostream_iterator



//读入一个文本,将其存入vector<string>中,并输出#include <iostream>#include <fstream>#include <vector>#include <string>#include <iterator>using std::string;int main(){    std::ifstream ifs("../data/book.txt");    std::istream_iterator<string> in(ifs), eof;    std::vector<string> vec;    std::copy(in, eof, back_inserter(vec));        // output    std::copy(vec.cbegin(), vec.cend(), std::ostream_iterator<string>(std::cout, "\n"));}

//读入数列,并排序无重复输出#include <iostream>#include <vector>#include <algorithm>#include <iterator>int main(){    std::istream_iterator<int> in_iter(std::cin), eof;    std::vector<int> vec;    while (in_iter != eof)        vec.push_back(*in_iter++);    std::sort(vec.begin(), vec.end());    std::unique_copy(vec.cbegin(), vec.cend(), std::ostream_iterator<int>(std::cout, " "));}

4.4 反向迭代器


//寻找并打印第一个单词auto comma=find(line.begin(),line.end(),',');cout<<string(line.begin(),comma)<<endl;//选择并打印最后一个单词auto rcomma=find(line.rbegin(),line.rend(),',');cout<<string(rcomma.base(),line.end());

//将v的3到7之间的数,逆序拷贝到I中; std::copy(v.crbegin() + 3, v.crbegin() + 8, std::back_inserter(l));

5 泛型算法结果



6 特定容器算法








原创粉丝点击