C++初学者指南-5.标准库(第二部分)--数值运算算法

news2024/11/26 18:21:56

C++初学者指南-5.标准库(第二部分)–数值运算算法

文章目录

  • C++初学者指南-5.标准库(第二部分)--数值运算算法
    • iota (注意不是itoa函数)
    • Reductions
      • reduce
      • transform_reduce
      • 遗留操作(无法并行执行)
        • accumulate (≈ reduce) C++98
        • inner_product (≈ transform_reduce) C++98
    • Scans (Prefix 'Sums')
      • adjacent_difference
      • inclusive_scan
      • exclusive_scan
      • transform_inclusive_scan
      • transform_exclusive_scan
      • 遗留操作(无法并行执行)
        • partial_sum (≈ inclusive_scan) C++98
    • 相关内容

不熟悉 C++ 的标准库算法? ⇒ 简介

#include <numeric>
Reductions 根据输入元素的序列产生一个结果。
Scans 生成一个结果序列,其元素数量与输入序列相同。

iota (注意不是itoa函数)

在这里插入图片描述
cppreference

std::vector<int> v;
v.resize(9,0);
// fill subrange (as shown in image)
iota(begin(v)+2, begin(v)+7, 1);
for (int x : v) { cout << x << ' '; }  // 0 0 1 2 3 4 5 0 0
// fill entire vector
iota(begin(v), end(v), 3);
for (int x : v) { cout << x << ' '; }  // 3 4 5 6 7 8 9 10 11

运行示例代码
在这里插入图片描述
cppreference

std::vector<int> v;
v.resize(5,0);
// NOTE: might not be available yet
// in many standard library implementations!
auto const result = ranges::iota(v, 3);
std::cout << result.value;  // 8
for (int x : v) { cout << x << ' '; }  // 3 4 5 6 7

运行示例代码

Reductions

reduce

在这里插入图片描述
归约运算⊕必须具有结合性和可交换性,因为它的应用顺序是不确定的。
cppreference

std::vector<int> v {1,9,7,3,2,8};
auto const sum = reduce(begin(v), end(v));  // 1+9+7+3+2+8 = 30
auto const s47 = reduce(begin(v), end(v), 47);  // 47+1+9+7+3+2+8 = 77
std::vector<double> w {2.0, 1.5, 3.0, 1.5};
auto const product = reduce(begin(w), end(w), 1.0, std::multiplies<>{});  
// double product = 1.0 * 2.0 * 1.5 * 3.0 * 1.5 = 13.5
// 并行执行: #include <execution>
auto const psum = reduce(std::execution::par, begin(v), end(v));

并行执行参考
运行示例代码
确保初始值ω的类型要么和输入元素的类型相同,要么是一个能表示更多值的类型!

// 较窄的初始值类型可能会导致信息丢失:
std::vector<double> v {1.2, 2.4};                     
auto const wtf = reduce(begin(v), end(v), 1);  
cout << wtf;  // 4                    int ^
auto const sum = reduce(begin(v), end(v), 1.0);  
cout << sum;  // 4.6               double ^^^

运行示例算法

transform_reduce

在这里插入图片描述
归约操作⊕必须具有结合性和可交换性,投影函数 f 必须没有副作用、没有状态,因为它们的应用顺序没有保证。
cppreference

std::vector<int> v {3,2,4};
auto f = [](int x) { return x*x; };
auto const rf = transform_reduce(begin(v), end(v), 1, std::plus<>{}, f);  
// rf = 1 + f(3) + f(2) + f(4) = 30

运行示例代码
在这里插入图片描述
这两种运算 ⊕ 和 ⊗ 都必须是具有结合性和交换性,因为它们的应用顺序没有保证。
cppreference

std::vector<double> x {1.0, 3.0, 5.0};
std::vector<double> y {2.0, 4.0, 8.0};
auto const rx1 = transform_reduce(begin(x), end(x), begin(y), 10.0);  
// rx1 = 10 + (1⋅2)+(3⋅4)+(5⋅8) = 64
auto const rx2 = transform_reduce(
    begin(x), end(x), begin(y), 0.0, 
    std::plus<>{}, std::divides<>{});  
// rx2 = 0.0 + (1/2)+(3/4)+(5/8) = 1.875

运行示例程序

遗留操作(无法并行执行)

accumulate (≈ reduce) C++98

在这里插入图片描述
更喜欢 C++17 的 std::reduce,因为它也可以并行执行。只有在使用非交换或非结合的归约操作 ⊕ 时,才使用 accumulate。
cppreference

std::vector<int> v {1,9,7,3,2,8};
auto const sum = accumulate(begin(v), end(v), 0);  // 1+9+7+3+2+8 = 30
auto const s47 = accumulate(begin(v), end(v), 47);  // 47+1+9+7+3+2+8 = 77
std::vector<double> w {2.0, 1.5, 3.0, 1.5};
auto const product = accumulate(begin(w), end(w), 1.0, std::multiplies<>{});
// double product = 1.0 * 2.0 * 1.5 * 3.0 * 1.5 = 13.5

运行示例代码

确保初始值ω的类型与输入元素的类型相同,或者是可以表示更多值的类型!

// 较窄的初始值类型可能会导致信息丢失:
std::vector<double> v {1.2, 2.4};                     
auto const wtf = accumulate(begin(v), end(v), 0);  
cout << wtf;  // 3                  int ^
auto const sum = accumulate(begin(v), end(v), 0.0);  
cout << sum;  // 3.6             double ^^^

运行示例代码

inner_product (≈ transform_reduce) C++98

在这里插入图片描述
更喜欢使用 C++17 的 std::transform_reduce,因为它也可以并行执行。
cppreference

std::vector<int> v {4,3,2,1};
std::vector<int> w {10,20,30,40};
auto const ip = inner_product(begin(v), end(v), begin(w), 50);  
// ip = 50 + (4⋅10)+(3⋅20)+(2⋅30)+(1⋅40) = 250
std::vector<double> num {1.0, 3.0, 5.0};
std::vector<double> den {2.0, 4.0, 8.0};
auto const res = inner_product(
    begin(num), end(num), begin(den), 0.0, 
    std::plus<>{}, std::divides<>{} );  
// res = 0.0 + (1/2)+(3/4)+(5/8) = 1.875

运行示例代码

Scans (Prefix ‘Sums’)

目标范围必须能够接收所有生成的元素!
这意味着,目标容器必须适当调整大小。
标准算法无法(在大多数情况下也不可能)检查目标范围是否足够大。
试图复制超出目标容量的元素会导致未定义的行为!

adjacent_difference

在这里插入图片描述
操作 ⊖ 不应有副作用 / 不应是有状态的,因为应用的顺序是不确定的。
cpprefernece

std::vector<int> in {1,2,6,8,3,6};
// 确认输出能存放计算结果
std::vector<int> out;
out.resize(in.size());
adjacent_difference(begin(in), end(in), begin(out));
for (int x : out) { cout << x << ' '; }  // 1 1 4 2 -5 3
// C++17: 能提供定制操作
adjacent_difference(begin(in), end(in), begin(out), std::plus<>{});
for (int x : out) { cout << x << ' '; }  // 1 3 8 14 11 9
adjacent_difference(begin(in), end(in), begin(out), std::multiplies<>{});
for (int x : out) { cout << x << ' '; }  // 1 2 12 48 24 18

运行示例代码

inclusive_scan

在这里插入图片描述
二元运算⊕必须具有结合性,因为它的应用顺序是不确定的。
cppreference

std::vector<int> in {2,1,7,5,3};
// make sure output can fit results
std::vector<int> out;
out.resize(in.size());
inclusive_scan(begin(in), end(in), begin(out));
for (int x : out) { cout << x << ' '; }  // 2 3 10 15 18
inclusive_scan(begin(in), end(in), begin(out), std::minus<>{});
for (int x : out) { cout << x << ' '; }  // 2 1 -6 -11 -14
// with offset '3':
inclusive_scan(begin(in), end(in), begin(out), std::plus<>{}, 3);
for (int x : out) { cout << x << ' '; }  // 5 6 13 18 21

运行示例代码

exclusive_scan

在这里插入图片描述
二元运算⊕必须具有结合性,因为它的应用顺序是不确定的。
cppreference

std::vector<int> in {2,1,7,5,3};
// make sure output can fit results
std::vector<int> out;
out.resize(in.size());
exclusive_scan(begin(in), end(in), begin(out), 0);
for (int x : out) { cout << x << ' '; }  // 0 2 3 10 15
// with offset '3':
exclusive_scan(begin(in), end(in), begin(out), 3);
for (int x : out) { cout << x << ' '; }  // 3 5 6 13 18
exclusive_scan(begin(in), end(in), begin(out), 0, std::minus<>{});
for (int x : out) { cout << x << ' '; }  // 0 -2 -3 -10 -15

运行示例代码

transform_inclusive_scan

在这里插入图片描述
运算⊕必须具有结合性,投影函数 f 必须没有副作用、没有状态,因为它们应用的顺序无法保证。
cppreference

// returns value only if even and 0 if odd
auto even_only = [](int x) { return (x & 1) ? 0 : x; };
std::vector<int> in {2,1,6,4,3};
// make sure output can fit results
std::vector<int> out;
out.resize(in.size());
transform_inclusive_scan(
  begin(in), end(in), begin(out), std::plus<>{}, even_only);
for (int x : out) { cout << x << ' '; }  // 2 2 8 12 12
// with offset '3':
transform_inclusive_scan(
  begin(in), end(in), begin(out), std::plus<>{}, even_only, 3);
for (int x : out) { cout << x << ' '; }  // 5 5 11 15 15
// with projection f(x) = -x2:
transform_inclusive_scan(
  begin(in), end(in), begin(out), std::plus<>{}, 
  [](int x) { return -(x*x); });
for (int x : out) { cout << x << ' '; }  // -4 -5 -41 -57 -66

运行示例代码

transform_exclusive_scan

在这里插入图片描述
运算⊕必须具有结合性,投影函数 f 必须没有副作用、没有状态,因为它们应用的顺序无法保证。
cppreference

// returns value only if even and 0 if odd
auto even_only = [](int x) { return (x & 1) ? 0 : x; };
std::vector<int> in {2,1,6,4,3};
// make sure output can fit results
std::vector<int> out;
out.resize(in.size());
transform_exclusive_scan(
  begin(in), end(in), begin(out), 0, std::plus<>{}, even_only);
for (int x : out) { cout << x << ' '; }  // 0 2 2 8 12
// with offset '3':
transform_exclusive_scan(
  begin(in), end(in), begin(out), 3, std::plus<>{}, even_only);
for (int x : out) { cout << x << ' '; }  // 3 5 5 11 15
// with projection f(x) = -x2:
transform_exclusive_scan(
  begin(in), end(in), begin(out), 0, std::plus<>{}, 
  [](int x) { return -(x*x); });
for (int x : out) { cout << x << ' '; }  // 0 -4 -5 -41 -57

运行示例代码

遗留操作(无法并行执行)

partial_sum (≈ inclusive_scan) C++98

在这里插入图片描述
更喜欢C++17的std::inclusive_scan,因为它也可以并行执行。只有在归约操作⊕是非结合的情况下才使用partial_sum。
cppreference

std::vector<int> in {1,1,2,2,1,1};
// make sure output can fit results
std::vector<int> out;
out.resize(in.size());
partial_sum(begin(in), end(in), begin(out));
for (int x : out) { cout << x << ' '; }  // 1 2 4 6 7 8
partial_sum(begin(in), end(in), begin(out), std::minus<>{});
for (int x : out) { cout << x << ' '; }  // 1 0 -2 -4 -5 -6

相关内容

视频:partial_sum, iota by Conor Hoekstra
视频:accumulate, reduce by Conor Hoekstra
标准算法概述
C++标准库算法介绍
标准序列容器(vector、deque、list、…)
标准关联容器(map、set、…)
标准序列视图
cppreference:算法库
cppreference:容器库
视频:什么是 C++ 标准库?
视频:一小时内掌握 105 个 STL 算法 (Jonathan Boccara,2018)
C++ 之旅:容器和算法
算法概述表:
在这里插入图片描述
附上原文链接
如果文章对您有用,请随手点个赞,谢谢!^_^

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1985665.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

sanger序列拼接--一次错误示范

文章目录 目的实现步骤 目的 NGS得到了很多的reads&#xff0c;其中有一些paired reads我想根据overlap 搭建起来&#xff0c;因为我对序列的ID做了删减&#xff0c;所以再pandaseq那里跑不通。 总结来说&#xff0c;目的很简单&#xff0c;就是把 有重叠区域的 reads 搭起来…

【学习笔记】A2X通信的协议(二)- A2X配置参数

目录 5. A2X配置参数 5.1 一般说明 5.2 A2X配置参数的配置和优先级 5.2.1 一般说明 5.2.2 A2X配置参数的优先级 5.2.3 通过PC5进行的A2X通信的配置参数 5.2.4 广播远程ID&#xff08;BRID&#xff09;的配置参数 5.2.5 直接检测和避免&#xff08;DDAA&#xff09;的配…

解决 Beyond Compare 30天过期问题

解决 Beyond Compare 30天过期的步骤如下&#xff1a; 1、使用快捷键WinR打开运行窗口&#xff0c;输入regedit并回车&#xff0c;打开注册表编辑器。 2、在注册表编辑器中&#xff0c;找到Beyond Compare的注册表位置&#xff0c;路径通常是HKEY_CURRENT_USER\Software\Scoot…

【redis】springboot 用redis stream实现MQ消息队列 考虑异常ack重试场景

redis stream是redis5引入的特性&#xff0c;一定程度上借鉴了kafka等MQ的设计&#xff0c;部署的redis版本必须 > 5 本文主要讲的是思路&#xff0c;结合简单的源码分析&#xff08;放心&#xff0c;无需深入大量源码&#xff09;&#xff1b;讲述在redis stream文档缺乏&a…

港科夜闻 | 香港科大,中大,港大及国大获旭日慈善基金捐款港币五千万元,支持基础数学研究及人才发展...

关注并星标 每周阅读港科夜闻 建立新视野 开启新思维 1、香港科大、中大、港大及国大获旭日慈善基金捐款港币五千万元&#xff0c;支持基础数学研究及人才发展。香港科大校长叶玉如教授在会上代表四所大学&#xff0c;就旭日慈善基金会对推动高等教育及基础研究发展的慷慨支持&…

探索智谱AI的视频生成神器:CogVideoX完全指南

引言 在当今数字化和内容创作高度发达的时代&#xff0c;视频已经成为信息传播和营销的重要工具。然而&#xff0c;对于许多缺乏视频制作经验或资源的个人和企业而言&#xff0c;如何快速、高效地创建吸引人的视频仍然是一个挑战。智谱AI推出的CogVideoX&#xff0c;作为一款先…

PuerTS和HybridCLR哪个更适合开发微信小游戏

1&#xff09;PuerTS和HybridCLR哪个更适合开发微信小游戏 2&#xff09;使用了Play Asset Delivery提交版本被Google报错 3&#xff09;怎样设置normalize来改变摄像机位置 4&#xff09;如何禁用增强型输入法中除某些输入操作之外的输入操作 这是第397篇UWA技术知识分享的推送…

CodeWave常用功能

1、CodeWave添加H5或PC端 CodeWave在左侧侧边栏&#xff0c;可通过“”按钮&#xff0c;直接添加PC端或H5端&#xff0c;或添加页面。 2、修改主题颜色 CodeWave左侧栏对应端的更多按钮中&#xff0c;可对权限及主题色进行修改。 在主题样式修改页面&#xff0c;右侧提供了预…

视频监控汇聚平台LntonCVS视频监控管理平台解决方案和常见的接入方式

一、视频融合平台 LntonCVS是一款支持多种协议和设备接入的视频汇聚流媒体平台。它能够统一管理和整合不同品牌、不同协议的视频资源&#xff0c;构建视频数据资源池&#xff0c;并通过视频资源目录为各类业务场景提供丰富、实时、高清的视频资源。 二、接入方式 1. 前端设备…

成都跃享未来教育咨询抖音小店共绘未来发展

在数字经济的浪潮中&#xff0c;教育行业正经历着前所未有的变革与升级。成都&#xff0c;这座历史悠久而又充满活力的城市&#xff0c;正以其独特的地理位置、深厚的文化底蕴和前瞻性的发展战略&#xff0c;孕育着教育创新的新篇章。其中&#xff0c;成都跃享未来教育咨询抖音…

水域救援设备,保护水域安全_鼎跃安全

季作为一年中最炎热的季节&#xff0c;不仅带来了难耐的高温&#xff0c;也悄然间加剧了水域安全问题的严峻性。这一时期&#xff0c;正值学生群体享受悠长暑假的宝贵时光&#xff0c;他们往往倾向于寻找清凉之地以解酷暑&#xff0c;水域因此成为了不少学生的首选之地。然而&a…

Linux(CentOS)环境搭建Gitea做私有的git服务器

基本分三大步骤&#xff0c;1.安装Gitea&#xff0c;2.安装MySQL&#xff08;或者SQlite等其中一款数据库&#xff09;3.安装Git 一.Gitea Gitea文档地址&#xff1a;文档 - Docs (gitea.io) Gitea的官网&#xff1a;https://gitea.io Gitea最新版本的下载地址&#xff1a;…

【一竞技CS2】Twistzz秋季小组赛rating最高指挥

1、BLAST秋季小组赛于刚刚落下帷幕&#xff0c;数据统计显示&#xff0c;Liquid战队选手Twistzz是秋季小组赛里Rating最高指挥。 2、HLTV发布本周最新世界排名。TOP10战队方面凭借着在小组赛双杀NAVI头名晋级&#xff0c;Liquid战队新阵容一跃进入TOP10的行列&#xff0c;目前位…

湖北职称评审条件是什么?

其实湖北职称评审&#xff0c;要求很多&#xff0c;具体是根据评审专业大类来划分的&#xff0c;不同的专业要求略微有不同&#xff0c;主要是表现在相应的资料准备上&#xff0c;那么职称具体的有哪些要求&#xff1f; 别老听别人说湖北职称申报要求是什么&#xff0c;甘建二告…

基于R语言生物信息学大数据分析与绘图

随着高通量测序以及生物信息学的发展&#xff0c;R语言在生物大数据分析以及数据挖掘中发挥着越来越重要的作用。想要成为一名优秀的生物数据分析者与科研团队不可或缺的人才&#xff0c;除了掌握对生物大数据挖掘与分析技能之外&#xff0c;还要具备一定的统计分析能力与SCI论…

文本加密工具类-支持MD5、SHA1、SHA256、SHA224、SHA512、SHA384、SHA3、RIPMD160算法

文本加密工具类 1.算法简介1.1 MD51.2 SHA-11.3 SHA-2&#xff08;推荐使用&#xff09;1.4 SHA-3&#xff08;推荐使用&#xff09;1.5 RIPEMD-160 2.工具类案例2.1POM导入2.2代码编写2.3 输出示例 1.算法简介 1.1 MD5 MD5 (Message-Digest Algorithm 5) 描述&#xff1a;M…

一文理清生产管理的“4管”和“8理”!

一提到生产管理&#xff0c;很多人的第一反应可能是车间里忙碌的身影、流水线上飞速运转的机器&#xff0c;还有一张张密密麻麻的生产计划表。但实际上&#xff0c;生产管理远不止于此。 “科学管理之父”弗雷德里克温斯洛泰勒认为&#xff1a;管理就是确切地知道你要别人干什…

【Python】数据类型之元组

列表&#xff08;list&#xff09;是一个有序且可变的容器&#xff0c;在里面可以存放多个不同类型的元素。 元组&#xff08;tuple&#xff09;是一个有序且不可变的容器&#xff0c;在里面可以存放多个不同类型的元素。 1、定义 元组中的元素与元素之间用逗号相隔&#xf…

mybatis插件代码生成。

mybatis插件代码生成。 第一步连接数据库&#xff1a;第二步&#xff0c;选择数据库表&#xff1a;第三步&#xff0c;进行配置选择第四步、就生成了有关于表的实体类和其他的表数据。 第一步连接数据库&#xff1a; 在右边&#xff0c;拉出数据库的操作栏 输入用户名密码&am…

虚拟机Windows10系统安装QEMU

文章目录 1. QEMU安装1.1 安装准备1.1.1 安装平台1.1.2 软件下载 1.2 安装QEMU1.2.1 找到下载的QEMU软件&#xff0c;双击开始安装1.2.2 设置语言1.2.3 安装向导&#xff0c;点击 Next1.2.4 点击“I Agree”1.2.5 点击Next1.2.6 设置软件安装位置1.2.7 点击 finish1.2.8 编辑系…