CppPrimer笔记 Chapter10 泛型算法

CppPrimer笔记 Chapter10 泛型算法

标签: Cpp



概述(10.1)

  • find(vec.it1,vec.it2,val); [it1,it2) 中寻找 val ,找到则返回指向的容器,没找到则返回it2
  • 算法永远不会执行容器操作,即添加,删除元素.其值运行于迭代器上.利用一般的迭代器,可以改变容器中的值,移动元素.利用特殊的迭代器插入器可以进行插入操作,但这时给这类迭代器赋值时迭代器自己进行的,而不是算法进行的.

初识泛型算法(10.2)

  • accumulate(v.cbegin(),v.cend(),0)第三个参参数作为求和起点,隐含着序列中元素与这个参数可以相加
  • equal(roster1.cbegin(),roster1.cend(),roster2.cbegin())判断roster1是否与roster2的前roster1.size()个相等,隐含了第二个序列至少与第一个一样长
  • back_inserter 接受一个指向容器的引用,返回一个与该容器绑定的插入迭代器,向该迭代器赋值即调用push_back将一个具有给定值的元素添加到容器中
  • 常用函数示例
    vector<int> vec;
    fill_n(back_inserter(vec), 15, 1);//添加15个1到vec
    fill_n(vec.begin(), 5, 0);//将vec前5个换为0

    int arr[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

    auto ret = copy(begin(arr), end(arr), vec.begin());//将arr值拷贝到vec中
    //vec = {0,1,2,3,4,5,6,7,8,9,1,1,1,1,1}
    if (ret == vec.end()){ cout << "re == vec.end" << endl; }//true
    replace(vec.begin(), vec.end(), 1, 10);//将vec中1换成10
    //vec = {0,10,2,3,4,5,6,7,8,9,10,10,10,10,10}
    vector<int> vec2;
    replace_copy(vec.cbegin(), vec.cend(), back_inserter(vec2), 10, 1);//将vec中10换成1后赋值给vec2,而原vec不变
  • 利用sortunique排序后删去重复元素
void elimDups(vector<string> &words)
{
    sort(words.begin(), words.end());
    auto end_unique = unique(words.begin(), words.end());
    words.erase(end_unique, words.end());
}

向算法传递函数(10.3.1)

  • stable_sort(words.begin(), words.end(), isShorter);按照isShorter()规定的规则来排序,同时stable_sort保持相等元素的原有顺序
  • 上行代码中isShorter是一个谓词,需满足严格弱序

lambda表达式(10.3.2-10.3.3)

  • lambda表达式格式[capture list](parameter list) -> return type{function body} 表示一个可调用的代码单元,我们可以将其理解为一个未命名的内联函数
  • lambda不能有默认参数
  • lambda包含return之外的任何语句,则编译器假定此lambda返回void

  • 定义lambda时,生成一个与lambda对应的新的未命名类类型.默认情况下,生成的类都包含一个所捕获变量的数据成员,在lambda对象创建时被初始化(而不像函数一样,在调用时拷贝)

  • 尤其注意引用拷贝时引用,指针,迭代器的有效性
  • 使用mutable使得按值捕获的lambda表达式可以修改被捕获变量的值

参数绑定(10.3.4)

  • 利用using std::placeholders来使用_n进行形参占位
  • auto newCallable = bind(callable,arg_list);来进行绑定,利用_n进行形参占位,从而被占位的形参达到像变量捕获的效果
  • auto g = bind(f,a,b,_2,c,_1)回想g(arg1,arg2)映射为f(a,b,arg2,c,arg1)`
  • youyu bild那些非占位符参数被拷贝到bind返回的可调用对象中,因而若要按引用传递,则必须使用ref()bind(print,ref(os),_1)

迭代器(10.4)

  • 插入迭代器
    vector<int> vec{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    auto iter = vec.begin() + 5;//*iter = 6
    auto it_in = inserter(vec, iter);
    *it_in = 20;
    //vec = {1 2 3 4 5 20 6 7 8 9 10}
    //*iter;//error 参见 顺序容器 插入后迭代器的有效性问题
    *it_in = 30;
    //vec = {1 2 3 4 5 20 6 7 8 9 10}

    list<int> lst = { 1, 2, 3, 4 };
    list<int> lst2, lst3;
    copy(lst.cbegin(), lst.cend(), front_inserter(lst2));
    //lst2 = {4,3,2,1}
  • 流迭代器:被绑定到输入或输出流上,可用来便利所关联的IO流
    • 在第一次解引用迭代器时才真正读取
    • istream_iterator默认初始化,可以当做尾后值使用
    • 不支持递减运算
    //将in_iter绑定在cin上,其为指向输入流数据的一个容器
    //eof默认初始化,可以当做尾后值使用
    istream_iterator<int> in_iter(cin),eof;
    while(in_iter != eof)
    //先解引用,然后指向下一个数字
    vec.push_back(*in_iter++);

        vector<int> vec2{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    ostream_iterator<int> out_iter(cout, " ");
    for (auto e:vec2)
    {
        *out_iter++ = e;
    }
    cout << " :out" << endl;
    //输出 1 2 3 4 5 6 7 8 9 10  :out
  • 反向迭代器
    • sort(vec.rbegin(),vec.rend());将最小元素放在vec的末尾
  • 移动迭代器P480

5类迭代器(10.5.1)

  • 输入迭代器
  • 输出迭代器
  • 前向迭代器
  • 双向迭代器
  • 随机访问迭代器

特定容器算法(10.6)

  • 链表特有的操作会改变容器

移动迭代器P480

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值