【C++之泛型算法】018数值算法

本文介绍了C++标准库中的四个重要算法:std::accumulate用于累积操作,std::inner_product计算内积,std::partial_sum生成部分和,std::adjacent_difference处理相邻元素的差或自定义操作。这些算法在处理序列数据时非常实用。
摘要由CSDN通过智能技术生成

accumulate()

std::accumulate 是 C++ 标准库中的一个泛型算法,用于计算一个序列中元素的累积和或其他累积操作。这个算法可以处理任何可以使用加法运算符的元素类型,并允许你提供一个自定义的二元操作来替代默认的加法。
泛型声明

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 );

其中:

  • InputIt 是一个输入迭代器的类型,指向序列中的元素。
  • first 和 last 定义了序列的范围,即 [first, last)。
  • T 是累积结果的类型,init 是累积的初始值。
  • BinaryOperation 是一个二元操作的类型,它接受两个参数并返回一个结果,用于替代默认的加法。

具体用法

以下是一些 std::accumulate 的具体用法示例:
示例 1:使用默认加法运算符

#include <iostream>
#include <vector>
#include <numeric> // for std::accumulate

int main() {
    std::vector<int> numbers = {1, 2, 3, 4, 5};
    int sum = std::accumulate(numbers.begin(), numbers.end(), 0);
    std::cout << "Sum: " << sum << std::endl; // 输出:Sum: 15
    return 0;
}

在这个例子中,我们计算了 numbers 向量中所有元素的和。初始值 init 是 0,表示从 0 开始累加。
示例 2:使用自定义二元操作

#include <iostream>
#include <vector>
#include <numeric> // for std::accumulate

int main() {
    std::vector<int> numbers = {1, 2, 3, 4, 5};
    int product = std::accumulate(numbers.begin(), numbers.end(), 1, std::multiplies<int>());
    std::cout << "Product: " << product << std::endl; // 输出:Product: 120
    return 0;
}

在这个例子中,我们计算了 numbers 向量中所有元素的乘积。初始值 init 是 1,表示从 1 开始累乘。std::multiplies() 是一个函数对象,提供了乘法操作。
示例 3:累积字符串中的字符

#include <iostream>
#include <string>
#include <numeric> // for std::accumulate

int main() {
    std::string str = "hello";
    std::string result = std::accumulate(str.begin(), str.end(), std::string(), [](const char& a, const char& b) {
        return std::string(1, a + b); // 创建一个只包含字符 a 和 b 之和的字符串
    });
    std::cout << "Accumulated string: " << result << std::endl; // 输出可能是:Accumulated string: hhlloo
    return 0;
}

在这个例子中,我们定义了一个 lambda 函数,将两个字符相加(实际上是将它们的 ASCII 值相加),并创建一个新的字符串,其中包含这个和对应的字符。然后,std::accumulate 使用这个 lambda 函数来累积字符串中的字符。

注意:std::accumulate 的结果类型 T 必须能够与序列中的元素类型以及二元操作的结果类型兼容。如果序列中的元素类型与二元操作的结果类型不同,或者与初始值 init 的类型不兼容,你可能需要提供适当的类型转换或使用适当的类型别名来确保类型匹配。

inner_product()

std::inner_product 是 C++ 标准库中的一个泛型算法,用于计算两个输入序列的内积(也称为点积)。这个算法对于计算两个向量之间的点积非常有用,也可以用于任何可以通过二元操作累积的元素序列。
泛型声明

std::inner_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 binary_op1, BinaryOperation2 binary_op2 );

其中:

  • InputIt1 和 InputIt2 是输入序列的迭代器类型。
  • first1 和 last1 定义了第一个输入序列的范围。
  • first2 是第二个输入序列的开始迭代器。
  • init 是累积的初始值。
  • BinaryOperation1 是一个二元操作,用于计算两个输入序列中对应元素的乘积(默认为乘法)。
  • BinaryOperation2 是一个二元操作,用于将累积结果和新的乘积相加(默认为加法)。

具体用法

以下是一些 std::inner_product 的具体用法示例:
示例 1:使用默认乘法和加法运算符

#include <iostream>
#include <vector>
#include <numeric> // for std::inner_product

int main() {
    std::vector<int> v1 = {1, 2, 3};
    std::vector<int> v2 = {4, 5, 6};

    // 计算内积:1*4 + 2*5 + 3*6
    int result = std::inner_product(v1.begin(), v1.end(), v2.begin(), 0);

    std::cout << "Inner product: " << result << std::endl; // 输出:Inner product: 32

    return 0;
}

在这个例子中,我们计算了两个向量 v1 和 v2 的内积。初始值 init 是 0,表示从 0 开始累积。
示例 2:使用自定义二元操作

#include <iostream>
#include <vector>
#include <numeric> // for std::inner_product
#include <functional> // for std::minus, std::plus

int main() {
    std::vector<int> v1 = {1, 2, 3};
    std::vector<int> v2 = {4, 5, 6};

    // 使用自定义的减法作为乘法操作,加法作为加法操作
    int result = std::inner_product(v1.begin(), v1.end(), v2.begin(), 0, std::minus<>(), std::plus<>());

    std::cout << "Custom inner product: " << result << std::endl; // 输出:Custom inner product: -2

    return 0;
}

在这个例子中,我们使用了自定义的二元操作 std::minus<>() 作为乘法操作(计算两个元素的差),和 std::plus<>() 作为加法操作(计算累积和)。这导致计算出的内积与常规内积不同。

请注意,std::inner_product 假定两个输入序列具有相同的长度,并且都是已排序的。如果序列长度不同,行为将是未定义的。

partial_sum()

std::partial_sum 是 C++ 标准库中的一个泛型算法,用于计算序列的部分和或其他部分累积操作。这个算法将结果存储在一个输出序列中,其中每个元素是输入序列中对应位置及其之前所有元素的累积结果。
泛型声明

std::partial_sum 有两个主要的声明形式:

  • 使用默认加法运算符:
template< class InputIt, class OutputIt >
OutputIt partial_sum( InputIt first, InputIt last, OutputIt d_first );
  • 使用自定义二元操作:
template< class InputIt, class OutputIt, class BinaryOperation >
OutputIt partial_sum( InputIt first, InputIt last, OutputIt d_first, BinaryOperation binary_op );

其中:

  • InputIt 是输入序列的迭代器类型。
  • OutputIt 是输出序列的迭代器类型,用于存储部分和。
  • first 和 last 定义了输入序列的范围。
  • d_first 是输出序列的开始迭代器,指向存储部分和的位置。
  • binary_op 是一个二元操作,用于替代默认的加法操作。

具体用法

以下是一些 std::partial_sum 的具体用法示例:
示例 1:使用默认加法运算符

#include <iostream>
#include <vector>
#include <numeric> // for std::partial_sum

int main() {
    std::vector<int> numbers = {1, 2, 3, 4, 5};
    std::vector<int> partialSums(numbers.size());

    // 计算部分和并将结果存储在 partialSums 中
    std::partial_sum(numbers.begin(), numbers.end(), partialSums.begin());

    // 输出部分和
    for (const auto& sum : partialSums) {
        std::cout << sum << ' ';
    }
    std::cout << std::endl; // 输出:1 3 6 10 15

    return 0;
}

在这个例子中,partialSums 向量被初始化为与 numbers 向量相同的大小。std::partial_sum 算法计算了 numbers 向量的部分和,并将结果存储在 partialSums 向量中。因此,partialSums[i] 存储了 numbers[0] + numbers[1] + … + numbers[i] 的和。
示例 2:使用自定义二元操作

#include <iostream>
#include <vector>
#include <numeric> // for std::partial_sum
#include <functional> // for std::multiplies

int main() {
    std::vector<int> numbers = {1, 2, 3, 4, 5};
    std::vector<int> products(numbers.size());

    // 计算部分乘积并将结果存储在 products 中
    std::partial_sum(numbers.begin(), numbers.end(), products.begin(), std::multiplies<int>());

    // 输出部分乘积
    for (const auto& product : products) {
        std::cout << product << ' ';
    }
    std::cout << std::endl; // 输出:1 2 6 24 120

    return 0;
}

在这个例子中,我们使用 std::multiplies() 作为二元操作来计算 numbers 向量的部分乘积,而不是部分和。因此,products[i] 存储了 numbers[0] * numbers[1] * … * numbers[i] 的乘积。

std::partial_sum 算法是一个非常有用的工具,特别是在需要进行累积操作的情况下,如计算滑动平均、累积百分比等。

adjacent_difference()

std::adjacent_difference 是 C++ 标准库中的一个泛型算法,用于计算一个序列中相邻元素的差(或其他二元操作的结果),并将这些差(或结果)存储在一个输出序列中。该算法通常用于计算差分序列或进行类似的操作。
泛型声明

std::adjacent_difference 有两个主要的声明形式:

  • 使用默认减法运算符:
template< class InputIt, class OutputIt >
OutputIt adjacent_difference( InputIt first, InputIt last, OutputIt d_first );
  • 使用自定义二元操作:
template< class InputIt, class OutputIt, class BinaryOperation >
OutputIt adjacent_difference( InputIt first, InputIt last, OutputIt d_first, BinaryOperation binary_op );

其中:

  • InputIt 是输入序列的迭代器类型。
  • OutputIt 是输出序列的迭代器类型,用于存储相邻元素的差。
  • first 和 last 定义了输入序列的范围。
  • d_first 是输出序列的开始迭代器,指向存储相邻元素差的位置。
  • binary_op 是一个二元操作,用于替代默认的减法操作。

具体用法

以下是一些 std::adjacent_difference 的具体用法示例:
示例 1:使用默认减法运算符

#include <iostream>
#include <vector>
#include <numeric> // for std::adjacent_difference

int main() {
    std::vector<int> numbers = {1, 5, 9, 13, 17};
    std::vector<int> differences(numbers.size());

    // 计算相邻元素的差,并将结果存储在 differences 中
    std::adjacent_difference(numbers.begin(), numbers.end(), differences.begin());

    // 输出相邻元素的差
    for (const auto& diff : differences) {
        std::cout << diff << ' ';
    }
    std::cout << std::endl; // 输出:1 4 4 4

    return 0;
}

在这个例子中,differences 向量被初始化为与 numbers 向量相同的大小。std::adjacent_difference 算法计算了 numbers 向量中相邻元素的差,并将结果存储在 differences 向量中。因此,differences[i] 存储了 numbers[i] - numbers[i-1] 的差(对于 i > 0),而 differences[0] 被初始化为 numbers[0](因为没有前一个元素)。
示例 2:使用自定义二元操作

#include <iostream>
#include <vector>
#include <numeric> // for std::adjacent_difference
#include <functional> // for std::plus, std::multiplies

int main() {
    std::vector<int> numbers = {1, 2, 3, 4, 5};
    std::vector<int> products(numbers.size());

    // 计算相邻元素的乘积,并将结果存储在 products 中
    std::adjacent_difference(numbers.begin(), numbers.end(), products.begin(), std::multiplies<int>());

    // 输出相邻元素的乘积
    for (const auto& prod : products) {
        std::cout << prod << ' ';
    }
    std::cout << std::endl; // 输出:1 2 6 12 20

    return 0;
}

在这个例子中,我们使用了自定义的二元操作 std::multiplies() 来计算相邻元素的乘积,而不是默认的差。因此,products[i] 存储了 numbers[i] * numbers[i-1] 的乘积(对于 i > 0),而 products[0] 被初始化为 numbers[0]。

std::adjacent_difference 算法是一个非常有用的工具,它允许你轻松地计算序列中相邻元素的差或其他通过二元操作得到的结果。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

熊猫Devin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值