c++11の泛型算法

一、泛型算法泛型算法这个概念是针对容器操作的,我们知道,c++11的顺序容器有vector,list,deque等,对于这些容器,c++11并没给出相应的增删改查方法,而是定义了一组泛型算法

一般的泛型算法都定义在#include <algorithm>中,对于数值的有些算法则定义在#include <numeric>中

1、find

vector<int>::const_iterator result =  find(vec.begin(), vec.end(), search_value)

找到就返回指向该元素的迭代器,没找到就返回第二个迭代器实参

    vector<string> vec_test = { "I","love","c++" ,"and","I","know","how","to","user","it"};
    vector<string>::iterator it = find(vec_test.begin(), vec_test.end(), "it");              //最后一个值可以是lambda表达式,精确筛选
    cout<<*it<< endl;

由于 find 运算是基于迭代器的,因此可在任意容器中使用相同的 find 函数查找值。

类似地,由于指针的行为与作用在内置数组上的迭代器一样,因此也可以使用 find 来搜索数组:int ia[6] = {27, 210, 12, 47, 109, 83};

int *result = find(ia, ia + 6, 12);

2、accumulate

该算法在 numeric 头文件中定义。假设 vec 是一个 int 型的 vector 对象,下面的代码:

int sum = accumulate(vec.begin(), vec.end(), 42);

将 sum 设置为 vec 的元素之和再加上 42。第三个形参则是累加的初值。

用于指定累加起始值的第三个实参是必要的,因为 accumulate 对将要累加的元素类型一无所知

这个事实有两层含义。首先,调用该函数时必须传递一个起始值,否则,accumulate 将不知道使用什么起始值。其次,容器内的元素类型必须与第三个实参的类型匹配,或者可转换为第三个实参的类型。

    vector<int> vec_test = {15,8,2,3,4,8,6,3,5,1,5,57};
    int sum = accumulate(vec_test.cbegin(),vec_test.cend(),0);
    cout << sum;

3、find_first_of

这个算法带有两对迭代器参数来标记两段元素范围,在第一段范围内查找与第二段范围中任意元素匹配的元素,然后返回一个迭代器,指向第一个匹配的元素。如果找不到元素,则返回第一个范围的 end 迭代器。

    vector<string> vec_1{"what", "did", "i", "do"};
    vector<string> vec_2{ "no", "did", "you", "do" };
    vector<string>::const_iterator it = find_first_of(vec_1.cbegin(), vec_1.cend(), vec_2.cbegin(),vec_2.cend());
    cout << *it << endl;

4、fill

    vector<int> vec_test = {1,3,5,85,7,8,4,5};
    fill(vec_test.begin(), vec_test.end(), 0);
    vector<int>::iterator it = vec_test.begin();
    while (it!= vec_test.end())
    {
        cout << *it << endl;
        it++;
    }

5、fill _n

带有的参数包括:一个迭代器、一个计数器以及一个值。该函数从迭代器指向的元素开始,将指定数量的元素设置为给定的值。fill_n 函数假定对指定数量的元素做写操作是安全的。

初学者常犯的错误的是:在没有元素的空容器上调用 fill_n 函数(或者类似的写元素算法)。

    it = vec_test.begin();
    fill_n(vec_test.begin(), 2,10);
    while (it != vec_test.end())
    {
        cout << *it << endl;
        it++;
    }

6、back_inserter

这个函数是迭代器适配器,插入迭代器可以给基础容器添加元素的迭代器

使用 back_inserter 可以生成一个指向 fill_n 写入目标的迭代器:

    vector<int> vec;                      // empty
    fill_n(back_inserter(vec), 10, 0);
    auto it = vec.begin();
    while (it != vec.end())
    {
        cout << *it << endl;
        it++;
    }

7、copy

    list<int> ilst = { 34,5,43,43,543,58,87,9,1,3,5,45,4 };
    vector<int> ivec;                       // empty 
    copy(ilst.begin(), ilst.end(), back_inserter(ivec));
    auto it = ivec.begin();
    while (it != ivec.end())
    {
        cout << *it << endl;
        it++;
    }

8、replace

这个算法接受第三个迭代器实参,指定保存调整后序列的目标位置。

如果不想改变原来序列,调用replace_copy()

调用该函数后,ilst 没有改变,ivec 存储 ilst 一份副本,而 ilst 内所有的 0 在 ivec 中都变成了 42。

    list<int> ilst = { 24,24,24,24,24 };
    replace(ilst.begin(), ilst.end(), 24, 42);
    auto it = ilst.begin();
    while (it != ilst.end())
    {
        cout << *it << endl;
        it++;
    }

    list<int> ilst = { 24,24,24,24,24 };
    vector<int> vec;
    replace_copy(ilst.begin(), ilst.end(),back_inserter(vec),24, 42);
    auto it = ilst.begin();
    while (it != ilst.end())
    {
        cout << *it << endl;
        it++;
    }
    auto it2 = vec.begin();
    while (it2 != vec.end())
    {
        cout << *it2 << endl;
        it2++;
    }

9、

对容器元素重新排序的算法

按单词长度排序  sort排序

去掉所有重复单词  调用 unique“删除”了相邻的重复值。给“删除”加上引号是因为 unique 实际上并没有删除任何元素,而是将无重复的元素复制到序列的前端,从而覆盖相邻的重复元素。unique 返回的迭代器指向超出无重复的元素范围末端的下一位置。然后用erase

统计长度等于或超过6个字符的单词个数 

    auto GT6 = [](const string &s) -> bool { return s.size() >= 5; };

    vector<string> vec = { "ok","work","over","handsome","red","red","slow","a","the","turtle" };
    sort(vec.begin(), vec.end());                                    //排序
    vector<string>::iterator it = unique(vec.begin(), vec.end());    //移动重复元素,返回不重复的下一个位置的迭代器
    vec.erase(it, vec.end());                                       //删除重复元素
    vector<string>::iterator it1 = vec.begin();
    int n = 0;
    while (it1 != vec.end())
    {
        if (GT6(*it1))
                n++;
        cout << *it1++ << " ";
    }
    cout << endl << "the words size no less than 5 have :" << n << endl;

 

posted @ 2019-03-13 16:25  卖雨伞的小男孩  阅读(224)  评论(0编辑  收藏  举报