cpp primer笔记070-算法函数

2023-10-07 07:20
文章标签 算法 函数 笔记 cpp primer 070

本文主要是介绍cpp primer笔记070-算法函数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  1. accumulate的第三个参数的类型决定了函数中使用哪个加法运算符以及返回值的类型,如果返回值是自定义类型,需要使用accumlate,则需要重载运算符,该接口的第三个参数返回的是一个需要处理的数据类型的一个变量。

    std::vector<std::string> v{ "wer","Sdf","sdf" };
    std::string sum = std::accumulate(v.begin(), v.end(), std::string(""));
    std::cout << sum << std::endl;
    
    werSdfsdf
    
  2. fill接受一对迭代器表示一个范围,还接受一个值作为第三个参数,将该范围的所有元素的值初始化为该参数。如果使用fill_n,很可能导致数组越界而产生异常。

    std::vector<std::string> v{ "wer","Sdf","sdf" };
    std::fill(v.begin(), v.end(), "wer");
    for (auto x : v)
    {std::cout << x << " ";
    }
    std::fill_n(v.begin(), v.size(), "2");
    for (auto x : v)
    {std::cout << x << " ";
    }
    
    wer wer wer 2 2 2
    
  3. lambda表达式一般构成部分为一下四种,(注意:lambda表达式不能有默认参数,捕获列表只能用于局部非静态变量,对于局部静态变量和全局变量可以直接使用,如果采取值捕获的方式,则变量可以被拷贝,并且被捕获的变量的值是在lambda创建时拷贝的,而不是调用的时候。若采取引用类型捕获的话,如果引用的变量在lambda表达式被调用的时候已经被销毁,则会产生异常。如果想要改变被捕获的值而不是引用变量,则lambda-specifiers可以是mutable):

    • [captures] &lttparams&gt (params) lambda-specifiers { body }
    • [captures] (params) trailing-return-type { body }
    • [captures] (params) { body }
    • [captures] lambda-specifiers { body }
    • captures:捕获列表,lambda可以把上下文变量以值或者引用的方式捕获,在body中直接使用。
    • tparams模板参数列表:让lambda可以像模板函数一样被调用。
    • params参数列表,相当于函数的产生列表,在C++14之后允许使用auto左右参数类型,可以省略。
    • lambda-specifiers lambda说明符,一些可选的参数,比较常用的的参数包括mutable和exception
    • trailing-return-type返回值类型,一般可以省略掉,由编译器来推导。
    • body函数体,函数的具体逻辑。
      [captures]可以使用的几种常用捕获方式:
    • []什么也不捕获,lambda无法使用所在函数体内任何变量。
    • [=]按值的方式捕获所有变量。
    • [&]按引用的方式捕获所有变量。
    • [=,&a,&b]除了变量a和b按引用捕获,其他按值捕获。(这里如果a不加&号会报错)
    • [&,a,b,c]除了变量a,b,c按值捕获,其他按引用捕获
    • [a,&b,&c]以值的方式捕获a,以引用的方式捕获b和c
    • [this]在成员函数中,可以直接捕获this指针,其实在成员函数中,[=]和[&]也会捕获this指针。
    #include <iostream>
    #include <fstream>
    #include <array>
    #include <vector>
    #include <string>
    #include <exception>
    #include <stack>
    #include <deque>
    #include <numeric>
    class Vector3
    {
    private:double x = 0;double y = 0;double z = 0;
    public:Vector3(double a, double b, double c) :x(a), y(b), z(c) {};const Vector3 operator+(const Vector3& vec) const{return [this](const Vector3& vec)->Vector3{ return { double(this->x + vec.x),double(this->y + vec.y),double(this->z + vec.z) }; }(vec);}Vector3& operator=(const Vector3& vec){auto ptrFunc = [this](const Vector3& vec) ->Vector3& {this->x = vec.x;this->y = vec.y;this->z = vec.z;return *this;};return ptrFunc(vec);}friend void Swap(Vector3& vec1, Vector3& vec2){[&vec1](Vector3& vec2){Vector3 tempVec = vec1;vec1 = vec2;vec2 = tempVec;}(vec2);}friend std::ostream& operator<<(std::ostream& os, const Vector3 vec){os << "Vector3 (" << vec.x << ", " << vec.y << ", " << vec.z << ")";return os;}
    };
    int main()
    {Vector3 vec1{ 1.0, 2.0, 3.0 }, vec2{ 4.0, 5.0, 6.0 };std::cout << vec1 << " " << vec2 << std::endl;std::cout << vec1 + vec2 << std::endl;Swap(vec1, vec2);std::cout << vec1 << " " << vec2 << std::endl;return 0;
    }
    
    Vector3 (1, 2, 3) Vector3 (4, 5, 6)
    Vector3 (5, 7, 9)
    Vector3 (4, 5, 6) Vector3 (1, 2, 3)
    
  4. bind函数的第一个参数是一个函数指针,后面的参数是这个函数指针中的参数列表,返回值为一个函数指针,其中_1,_2代表bind中第二个参数,第三个参数。

    using namespace std::placeholders;
    int main()
    {int a = 10, b = 20;auto max = std::bind([](int a, int b, int c) {return a > b ? a : b; }, a, b, _1);std::cout << max(a, b) << std::endl;std::cout << std::bind(max, a, b)(a, b) << std::endl;return 0;
    }
    
  5. iterator头文件定义了额外的一下几种迭代器:

    • 插入迭代器:这些迭代器被绑定到一个容器上,可以用来向容器插入元素。
    • 流迭代器:这些迭代器被绑定到输入或者输出流上,可以用来遍历所有关联的IO流。
    • 反向迭代器:这些迭代器向后移动,而不是向前移动,除了forward_list之外的标准库容器都有反向迭代器。
    • 移动迭代器:这些专用的迭代器不是拷贝其中的元素,而是移动他们。
  6. 插入迭代器包括back_inserter,front_inserter和inserter

    #include <iostream>
    #include <fstream>
    #include <array>
    #include <vector>
    #include <string>
    #include <exception>
    #include <algorithm>
    #include <stack>
    #include <deque>
    #include <numeric>
    #include <functional>
    int main()
    {std::deque<int> deq1, deq2;auto it = std::back_inserter(deq1);*it = 42;*it = 10;//vec.resize(10);//std::fill_n(vec.begin(), 10, 0);//下面的一行相当于上面的两行,由于插入迭代器自增无效,解引用,//所以fill_n不断让迭代器自增的语句无效,但是赋值语句有效std::fill_n(std::back_inserter(deq1), 10, 0);std::for_each(deq1.cbegin(), deq1.cend(), [](int val) {std::cout << val << " "; });deq1.clear();std::cout << std::endl;for (int i = 0; i < 10; ++i) *it = i;std::copy(deq1.cbegin(), deq1.cend(), std::front_inserter(deq2));std::for_each(deq2.cbegin(), deq2.cend(), [](int val) {std::cout << val << " "; });deq2.clear();std::cout << std::endl;std::copy(deq1.cbegin(), deq1.cend(), std::inserter(deq2, deq2.begin()));std::for_each(deq2.cbegin(), deq2.cend(), [](int val) {std::cout << val << " "; });return 0;
    }
    //给back_inserter赋值相当于push_back,给inserter相当于push_front
    //给front_inserter赋值相当于push_front
    
    42 10 0 0 0 0 0 0 0 0 0 0
    9 8 7 6 5 4 3 2 1 0
    0 1 2 3 4 5 6 7 8 9
    

    ![[Pasted image 20230922214426.png]]

  7. 流迭代器包括istream_iterator和ostream_iterator
    ![[Pasted image 20230922231536.png]]
    ![[Pasted image 20230923000228.png]]

		#include <iostream>#include <fstream>#include <array>#include <vector>#include <string>#include <exception>#include <algorithm>#include <stack>#include <deque>#include <numeric>#include <functional>int main(){std::vector<int> vec1;std::vector<char> vec2;std::istream_iterator<int> ini_it(std::cin);std::istream_iterator<int> int_eof;//上一个语句声明了开头//,下一个语句只要是类型相同就会声明一个结尾std::ifstream in("sdfksjdfk");//从sdfksjdfk文件读取字符串,而不是从这个字符串中读取std::istream_iterator<char> str_begin(in);std::istream_iterator<char> str_end;//std::cout << std::accumulate(ini_it, int_eof, 0) << std::endl;//上面的语句会使得ini_it自增不断从输入流读出下一个字符while (ini_it!=int_eof){auto it = std::back_inserter(vec1);*it = *ini_it++;}std::for_each(vec1.begin(), vec1.end(), [](int val) {std::cout << val << " "; });std::cout.put(10);while (str_begin != str_end){vec2.push_back(*str_begin++);}for (auto ch : vec2){std::cout << ch;}std::cout << std::endl;return 0;}
	123235234 534^Z123 235 234 534
	#include <iostream>#include <fstream>#include <array>#include <vector>#include <string>#include <exception>#include <algorithm>#include <stack>#include <deque>#include <numeric>#include <functional>int main(){std::vector<int> vec{ 1, 2, 34, 45, 5, 32134, 234 };std::ostream_iterator<int> out(std::cout, ",");for (auto x : vec)out = x;std::cout << std::endl;std::copy(vec.cbegin(), vec.cend(), out);std::cout << std::endl;return 0;}
1,2,34,45,5,32134,234,
1,2,34,45,5,32134,234,
  1. 反向迭代器包括rbegin,rend,crbegin,crend
    #include <iostream>
    #include <fstream>
    #include <array>
    #include <vector>
    #include <string>
    #include <exception>
    #include <algorithm>
    #include <stack>
    #include <deque>
    #include <numeric>
    #include <functional>
    int main()
    {std::vector<int> vec{ 1, 2, 3, 5, 6, 7, 8, 9 };std::ostream_iterator<int> out(std::cout, ",");for (auto r_iter = vec.crbegin(); r_iter != vec.crend(); ++r_iter){out = *r_iter;}std::cout.put(10).put(10);std::sort(vec.rbegin(), vec.rend());for_each(vec.cbegin(), vec.cend(), [&out](int val) { out = val; });return 0;
    }
    
    9,8,7,6,5,3,2,1,9,8,7,6,5,3,2,1,
    
  2. list和forward_list成员函数版本的算法
    ![[Pasted image 20230923092947.png]]

![[Pasted image 20230923093345.png]]

这篇关于cpp primer笔记070-算法函数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/156895

相关文章

Python中的随机森林算法与实战

《Python中的随机森林算法与实战》本文详细介绍了随机森林算法,包括其原理、实现步骤、分类和回归案例,并讨论了其优点和缺点,通过面向对象编程实现了一个简单的随机森林模型,并应用于鸢尾花分类和波士顿房... 目录1、随机森林算法概述2、随机森林的原理3、实现步骤4、分类案例:使用随机森林预测鸢尾花品种4.1

Oracle的to_date()函数详解

《Oracle的to_date()函数详解》Oracle的to_date()函数用于日期格式转换,需要注意Oracle中不区分大小写的MM和mm格式代码,应使用mi代替分钟,此外,Oracle还支持毫... 目录oracle的to_date()函数一.在使用Oracle的to_date函数来做日期转换二.日

C++11的函数包装器std::function使用示例

《C++11的函数包装器std::function使用示例》C++11引入的std::function是最常用的函数包装器,它可以存储任何可调用对象并提供统一的调用接口,以下是关于函数包装器的详细讲解... 目录一、std::function 的基本用法1. 基本语法二、如何使用 std::function

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第

【C++ Primer Plus习题】13.4

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: main.cpp #include <iostream>#include "port.h"int main() {Port p1;Port p2("Abc", "Bcc", 30);std::cout <<

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

hdu1171(母函数或多重背包)

题意:把物品分成两份,使得价值最接近 可以用背包,或者是母函数来解,母函数(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v) 其中指数为价值,每一项的数目为(该物品数+1)个 代码如下: #include<iostream>#include<algorithm>

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig