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

    使用泛型算法必须包含头文件#inlucde <algorithm>

    标准库还定义一组泛化的算术算法,其命名习惯与泛型算法相同,包含头文件#include <numeric>

    find

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

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

    1     vector<string> vec = {"a","b","c"};  //需要编译器支持C++11
    2     vector<string>::iterator it = find(vec.begin(),vec.end(),"a");
    3     string s = *it;
    4     cout<<s<<endl;

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

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

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

    accumulate

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

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

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

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

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

    find_first_of

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

    list<string>::iterator it = find_first_of(roster1.begin(), roster1.end(),roster2.begin(), roster2.end());

    roster1 和 roster2 的类型不必精确匹配:roster1 可以是 list 对象,而 roster2 则可以是 vector 对象,只要这两个序列的元素可使用相等(==)操作符进行比较即可。

    fill

    fill(vec.begin(), vec.end(), 0); // 将迭代器范围内元素值设置为0

    如果输入范围有效,则可安全写入。这个算法只会对输入范围内已存在的元素进行写入操作。

    fill_n

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

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

    vector<int> vec; // empty
    fill_n(vec.begin(), 10, 0);

    这个 fill_n 函数的调用将带来灾难性的后果。我们指定要写入 10 个元素,但这些元素却不存在——vec 是空的。其结果未定义,很可能导致严重的运行时错误。

    back_inserter

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

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

    vector<int> vec; // empty

    fill_n (back_inserter(vec), 10, 0);

    现在,fill_n 函数每写入一个值,都会通过 back_inserter 生成的插入迭代器实现。效果相当
    于在 vec 上调用 push_back,在 vec 末尾添加 10 个元素,每个元素的值都是 0。

    copy

    带有三个迭代器参数:头两个指定输入范围,第三个则指向目标序列的一个元素。传递给 copy 的目标序列必须至少要与输入范围一样大。假设 ilst 是一个存放 int 型数据的 list 对象,可如下将它 copy 给一个 vector 对象:

    vector<int> ivec; // empty
    copy (ilst.begin(), ilst.end(), back_inserter(ivec));

    copy 从输入范围中读取元素,然后将它们复制给目标 ivec。

    当然,这个例子的效率比较差:通常,如果要以一个已存在的容器为副本创建新容器,更好的方法是直接用输入范围作为新构造容器的初始化式:
    vector<int> ivec(ilst.begin(), ilst.end());

    replace

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

    replace(ilst.begin(),ilist.end(),0,42)

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

    vector<int> ivec;
    replace_copy (ilst.begin(), ilst.end(), back_inserter(ivec), 0, 42);

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

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

    按单词长度排序  sort排序

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

    统计长度等于或超过6个字符的单词个数  自己定义函数

     1 #include <iostream>
     2 using namespace std;
     3 #include <vector>
     4 #include <algorithm>
     5 
     6 bool GT6(const string &s)   //定义函数统计单词长度是否超过6
     7 {
     8     return s.size() >= 5;
     9 }
    10 
    11 int main()
    12 {
    13     vector<string> vec = {"fox","jumps","over","quick","red","red","slow","the","the","turtle"};
    14     sort(vec.begin(),vec.end());    //排序
    15     vector<string>::iterator it = unique(vec.begin(),vec.end());    //移动重复元素,返回不重复的下一个位置的迭代器
    16     vec.erase(it,vec.end());    //删除重复元素
    17 
    18     vector<string>::iterator it1 = vec.begin();
    19     int n = 0;
    20     while(it1 != vec.end())
    21     {
    22         if(GT6(*it1))
    23             n++;
    24         cout<<*it1++<<" ";
    25     }
    26     cout<<endl<<"the words size no less than 5 have :"<<n<<endl;
    27 
    28     return 0;
    29 }

     也可使用count_if函数统计,注意GT6没括号

    1 int n = count_if(vec.begin(),vec.end(),GT6);
    2     cout<<endl<<"the words size no less than 5 have :"<<n<<endl;

    再谈迭代器(P347 没怎么看)

    标准库所定义的迭代器不依赖于特定的容器

    其他的迭代器:插入迭代器,iostream迭代器,反向迭代器,const_iterator

  • 相关阅读:
    Webapi通过报文获取post上来的数据
    Jquery的跨域调用
    @html.ActionLink的几种参数格式
    MVC中使用RadioButtonFor
    string、Empty和null三者的区别
    JQuery中$.ajax()方法参数详解
    多线程与异步的区别
    IEnumerable,ICollection,IList,List之间的区别
    win10锁屏或睡眠一段时间后弹不出登录框
    ssh简明安全规划
  • 原文地址:https://www.cnblogs.com/raichen/p/4910224.html
Copyright © 2011-2022 走看看