C++ 标准库 numeric 功能 用法运用 详解

news/2025/3/9 19:53:14/文章来源:https://www.cnblogs.com/baisemoshui/p/18761253

C++标准库中的<numeric>头文件提供了一系列用于数值计算的函数模板,这些函数可以对容器中的元素进行各种数值操作,如求和、乘积、部分和、内积、相邻元素差等。以下是关于<numeric>头文件的功能、用法及详细解析:

一、功能概述

<numeric>头文件主要包含以下核心函数:

  1. std::accumulate:用于计算序列中元素的累积和(或其他累积操作)。
  2. std::inner_product:计算两个序列的内积。
  3. std::adjacent_difference:计算序列中相邻元素的差。
  4. std::partial_sum:生成一个包含序列部分和的序列。
  5. std::iota:生成从指定初始值开始的连续递增序列(填充容器)。

此外,C++17及以后的版本还引入了std::reducestd::transform_reduce等函数,进一步扩展了<numeric>的功能,支持并发计算和结合变换操作。不过,这里主要基于C++11标准讲解前五个函数的用法。

二、详细用法及解析

1. std::accumulate

  • 功能:计算序列中所有元素的累积和,或者以自定义的方式累积元素。
  • 语法
template<class InputIt, class T>
T accumulate(InputIt first, InputIt last, T init);template<class InputIt, class T, class BinaryOperation>
T accumulate(InputIt first, InputIt last, T init, BinaryOperation op);
  • 参数

    • firstlast:表示输入序列的范围。
    • init:累积计算的初始值。
    • op:可选的二元操作函数,用于指定累积规则。
  • 示例

#include <iostream>
#include <numeric>
#include <vector>int main() {std::vector<int> numbers = {1, 2, 3, 4, 5};int sum = std::accumulate(numbers.begin(), numbers.end(), 0); // 初始值为0std::cout << "Sum: " << sum << std::endl; // 输出: Sum: 15// 计算累积的乘积int product = std::accumulate(numbers.begin(), numbers.end(), 1, [](int a, int b) { return a * b; });std::cout << "Product: " << product << std::endl; // 输出: Product: 120return 0;
}

2. std::inner_product

  • 功能:计算两个序列的内积(dot product)。默认操作是计算两个序列中对应元素的乘积,并将结果相加,也可以通过自定义操作实现更复杂的计算。
  • 语法
template<class InputIt1, class InputIt2, class T>
T inner_product(InputIt1 first1, InputIt1 last1, InputIt2 first2, T init);template<class InputIt1, class InputIt2, class T, class BinaryOperation1, class BinaryOperation2>
T inner_product(InputIt1 first1, InputIt1 last1, InputIt2 first2, T init, BinaryOperation1 op1, BinaryOperation2 op2);
  • 参数

    • first1last1:第一个输入序列的范围。
    • first2:第二个输入序列的起始位置。
    • init:内积计算的初始值。
    • op1op2:自定义的二元操作函数,用于元素间的操作和累积规则。
  • 示例

#include <iostream>
#include <numeric>
#include <vector>int main() {std::vector<int> vec1 = {1, 2, 3};std::vector<int> vec2 = {4, 5, 6};int dotProduct = std::inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);std::cout << "Dot product: " << dotProduct << std::endl; // 输出: Dot product: 32return 0;
}

3. std::adjacent_difference

  • 功能:计算序列中相邻元素的差值,并将结果存储在另一个容器中。
  • 语法
template<class InputIt, class OutputIt>
OutputIt adjacent_difference(InputIt first, InputIt last, OutputIt result);template<class InputIt, class OutputIt, class BinaryOperation>
OutputIt adjacent_difference(InputIt first, InputIt last, OutputIt result, BinaryOperation op);
  • 参数

    • firstlast:输入序列的范围。
    • result:存储结果的容器的起始迭代器。
    • op:可选的二元操作函数,用于指定相邻元素间的操作。
  • 示例

#include <iostream>
#include <numeric>
#include <vector>int main() {std::vector<int> nums = {1, 3, 6, 10, 15};std::vector<int> diffs(nums.size());std::adjacent_difference(nums.begin(), nums.end(), diffs.begin());for (size_t i = 0; i < diffs.size(); ++i) {std::cout << diffs[i] << " "; // 输出: 1 2 3 4 5}std::cout << std::endl;return 0;
}

注意:diffs[0]总是等于nums[0],因为前面没有元素来形成差值。

4. std::partial_sum

  • 功能:计算序列中元素的部分和,并将结果存储在另一个容器中。
  • 语法
template<class InputIt, class OutputIt>
OutputIt partial_sum(InputIt first, InputIt last, OutputIt result);template<class InputIt, class OutputIt, class BinaryOperation>
OutputIt partial_sum(InputIt first, InputIt last, OutputIt result, BinaryOperation op);
  • 参数

    • firstlast:输入序列的范围。
    • result:存储结果的容器的起始迭代器。
    • op:可选的二元操作函数,用于指定部分和的计算规则。
  • 示例

#include <iostream>
#include <numeric>
#include <vector>int main() {std::vector<int> nums = {1, 2, 3, 4, 5};std::vector<int> partialSums(nums.size());std::partial_sum(nums.begin(), nums.end(), partialSums.begin());for (int sum : partialSums) {std::cout << sum << " "; // 输出: 1 3 6 10 15}std::cout << std::endl;return 0;
}

5. std::iota

  • 功能:生成从指定初始值开始的连续递增序列(填充容器)。
  • 语法
template<class ForwardIt, class T>
void iota(ForwardIt first, ForwardIt last, T value);
  • 参数

    • firstlast:要填充的容器的范围。
    • value:起始值。
  • 示例

#include <iostream>
#include <numeric>
#include <vector>int main() {std::vector<int> vec(5);std::iota(vec.begin(), vec.end(), 0); // 从0开始填充for (int val : vec) {std::cout << val << " "; // 输出: 0 1 2 3 4}std::cout << std::endl;return 0;
}

三、总结

<numeric>头文件提供了丰富的函数,可以简化在C++中进行数值计算的任务。这些函数大多是基于迭代器的,因此与STL容器的兼容性非常好。通过熟练使用这些函数,可以提高编程效率和代码质量。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

20242802 2024-2025-2 《网络攻防实践》第二周作业

20242802 2024-2025-2 《网络攻防实践》第二周作业 目录 目录20242802 2024-2025-2 《网络攻防实践》第二周作业1. 实验要求2. 实验相关知识点nmap工具使用3. 实验详细过程3.1 从www.besti.edu.cn、baidu.com、sina.com.cn中选择一个DNS域名进行查询,获取如下信息:3.2尝试获取…

UE5之瞄准视角的俯仰偏移

1.创建瞄准姿势 复制瞄准动画,删除其中多余的帧,只保留瞄准的一帧,将其创建为一个单帧动画。然后将其复制成三份,分别用于表示瞄准三个姿势的up,middle,down。 将middle姿势动画的Additive动画类型修改为网格体空间,因为我们需要在网格空间创建叠加动画。基础姿势修改为…

2K star!三分钟搭建企业级后台系统,这款开源Java框架绝了!

"LikeAdmin Java是基于Spring Boot + Mybatis Plus + Vue 3的快速开发平台,内置RBAC权限管理、工作流引擎、数据可视化、三方登录等核心模块,助力开发者快速构建企业级中后台管理系统"2K star!三分钟搭建企业级后台系统,这款开源Java框架绝了!"LikeAdmin J…

震惊!C++程序真的从main开始吗?99%的程序员都答错了

嘿,朋友们好啊!我是小康。今天咱们来聊一个看似简单,但实际上99%的C++程序员都答错的问题:C++程序真的是从main函数开始执行的吗? 如果你毫不犹豫地回答"是",那恭喜你,你和大多数人一样——掉进了C++的第一个陷阱!别担心,等你看完这篇文章,你就能成为那个与…

11套!量产15W~1000W开关电源电路全套方案资料合集!

本系列小编给大家带来了15W到1000W完整量产版开关电源全系列,全套资料分期给大家分享。每套资料都包含详细的原理图,PCB图,变压器图纸,共模电感图纸,磁环图纸!点击下方链接获取! 15W开关电源方案👆👆👆(点击下载) 25W开关电源方案👆👆👆(点击下载) 30W开…

【每日一题】20250309

我所渴望的,不过是过上一种发自本心的生活,为什么竟会如此困难?【每日一题】已知 \(\odot C\) 过点 \(P(1,2)\),与 \(y\) 轴相交于点 \(Q(0,6)\).若过点 \(Q\) 作 \(\odot C\) 的切线 \(l\),其切线 \(l\) 与 \(x\) 轴平行,则 \(l\) 的方程为_________,\(\odot C\) 的标…

FastAPI Cookie 和 Header 参数完全指南:从基础到高级实战

title: FastAPI Cookie 和 Header 参数完全指南:从基础到高级实战 🚀 date: 2025/3/9 updated: 2025/3/9 author: cmdragon excerpt: 本教程深入探讨 FastAPI 中 Cookie 和 Header 参数的读取与设置,涵盖从基础操作到高级用法。通过详细的代码示例、课后测验和常见错误解…

vim按f5运行代码配置

使vim能够像vscode一样按f5运行代码 效果图let g:last_terminal_buf = -1 " 用于存储上一个终端缓冲区编号 function! RunCurrentFile() " 如果存在上次的终端缓冲区,则删除它 if g:last_terminal_buf != -1 && bufexists(g:last_terminal_buf) silent exec…

DeepSeek + Xmind,1分钟自动把pdf/word文档转成思维导图

DeepSeek加Xmind,1分钟把PDF、Word文档转成思维导图!步骤超简单:第一步:打开DeepSeek,点击“深度思考”,上传你的文档。第二步:告诉DeepSeek“帮我转成思维导图,输出Markdown格式”。第三步:复制代码, 保存文件到桌面文本文件中,修改文件后缀为“.md”。第四步:打开…

Windows平台调试器原理与编写05.内存断点

https://www.bpsend.net/thread-274-1-3.html 内存断点访问断点 写入断点内存写入断点简介:当被调试进程访问,读或写指定内存的时候,程序能够断下来。 思考1:要想将一段内存设为内存断点,最终的目的是让其能够抛异常。调试器是基于异常的一个程序。应该如何实现呢?可以通…

Redis--Lesson01--NoSQL简史

单击MySQL的演进 单机MySQL 在早期互联网时代,也就是90年代以前,一个基本的互联网的访问量不会太大,可以说很多国家和地区都还没有配备互联网,所以在这种情况下的互联网格局使用的数据存储格式就是简单的单机模式,即使用一个数据库的如MySQL库就可以满足日常的数据读写 如…

Excel的快捷键

1、填充序号1~1000(删除后,序号会自动更新) (1)首先在左上角的位置框中输入A1:A1000,然后按Enter回车健,即可选中A1到A1000的单元格。(2)然后在函数框中输入=ROW(),按Ctrl + Enter即可,即可填充1-1000。 本文来自博客园,作者:业余砖家,转载请注明原文链接:http…