【C++之泛型算法】007复制元素

copy()

在C++标准库中,std::copy是一个泛型算法,它用于将一个序列的元素复制到另一个序列。该算法可以处理各种不同类型的容器,如数组、向量、列表等。

以下是std::copy的基本用法:

#include <algorithm>  // for std::copy
#include <vector>     // for std::vector
#include <iostream>   // for std::cout

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

    // 使用 std::copy 复制 v1 的元素到 v2
    std::copy(v1.begin(), v1.end(), v2.begin());

    // 打印 v2 的内容,应该与 v1 相同
    for(const auto& elem : v2) {
        std::cout << elem << " ";
    }

    return 0;
}

在上述示例中,std::copy算法接受三个迭代器参数:源序列的开始和结束,以及目标序列的开始。这个算法将源序列中的元素复制到目标序列中,直到源序列结束或者目标序列被填满为止。

需要注意的是,std::copy并不保证目标序列的大小足够大以容纳源序列的所有元素。如果目标序列的大小小于源序列,那么只有部分元素会被复制,并且可能会导致未定义的行为。因此,在使用std::copy之前,你需要确保目标序列有足够的空间来容纳源序列的所有元素。

另外,std::copy是一个泛型算法,这意味着它可以用于任何类型的元素,只要这些类型支持复制操作。例如,你也可以使用std::copy来复制std::string或自定义类型的序列。

copy_if()

std::copy_if 是 C++ 标准库中的一个泛型算法,它用于从一个输入范围复制那些满足特定条件的元素到一个输出范围。这个算法接受一个谓词(即一个返回布尔值的函数或函数对象),用于确定哪些元素应该被复制。

以下是 std::copy_if 的基本用法示例:

#include <algorithm>  // for std::copy_if
#include <vector>     // for std::vector
#include <iostream>   // for std::cout

// 谓词函数,用于检查元素是否为偶数
bool is_even(int n) {
    return n % 2 == 0;
}

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

    // 使用 std::copy_if 将 v1 中的偶数复制到 v2
    std::copy_if(v1.begin(), v1.end(), std::back_inserter(v2), is_even);

    // 打印 v2 的内容,应该只包含偶数
    for (const auto& elem : v2) {
        std::cout << elem << " ";
    }

    return 0;
}

在这个示例中,我们定义了一个简单的谓词函数 is_even,它检查一个整数是否是偶数。然后,我们使用 std::copy_if 算法,将 v1 中所有满足 is_even 条件的元素复制到 v2 中。std::back_inserter(v2) 是一个插入迭代器,它会在每次插入时自动调用 v2.push_back(),这样我们就不必手动管理 v2 的大小。

std::copy_if 的优点是它可以在不改变输入序列的情况下,根据特定条件选择性地复制元素。这对于过滤和转换数据非常有用。

copy_n()

std::copy_n 是 C++ 标准库中的另一个泛型算法,它用于从一个输入范围复制指定数量的元素到一个输出范围。与 std::copy 不同,std::copy_n 允许你指定要复制的元素的数量,而不是一直复制到输入范围的末尾。

以下是 std::copy_n 的基本用法示例:

#include <algorithm>  // for std::copy_n
#include <vector>     // for std::vector
#include <iostream>   // for std::cout

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

    // 使用 std::copy_n 复制 v1 的前 3 个元素到 v2
    v2.resize(3); // 确保 v2 有足够的空间来存储要复制的元素
    std::copy_n(v1.begin(), 3, v2.begin());

    // 打印 v2 的内容,应该包含 1, 2, 3
    for (const auto& elem : v2) {
        std::cout << elem << " ";
    }

    return 0;
}

在这个例子中,我们使用了 std::copy_n 来从 v1 中复制前 3 个元素到 v2。首先,我们调用了 v2.resize(3) 来确保 v2 有足够的空间来存储这 3 个元素。然后,我们调用了 std::copy_n,并传递了 v1.begin() 作为源范围的开始迭代器,3 作为要复制的元素数量,以及 v2.begin() 作为目标范围的开始迭代器。

std::copy_n 的优点是它允许你精确地控制要复制的元素数量,这在处理大型数据集或只需要部分数据时非常有用。同样,这个算法也是泛型的,可以用于任何类型的元素,只要这些类型支持复制操作。

copy_backward()

std::copy_backward 是 C++ 标准库中的一个算法,用于将源序列中的元素从尾部向前复制到目标序列的尾部。与 std::copy 和 std::copy_n 不同,std::copy_backward 是从源序列的末尾开始复制,一直到源序列的开始。

以下是 std::copy_backward 的基本用法示例:

#include <algorithm>  // for std::copy_backward
#include <vector>     // for std::vector
#include <iostream>   // for std::cout

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

    // 初始化 destination 为一个递增序列
    std::iota(destination.begin(), destination.end(), 0);

    // 使用 std::copy_backward 从 source 复制元素到 destination
    std::copy_backward(source.begin(), source.end(), destination.end());

    // 输出 destination 的内容,现在应该是 5 4 3 2 1
    for (const auto& elem : destination) {
        std::cout << elem << " ";
    }

    return 0;
}

在这个示例中,std::copy_backward 将 source 中的元素从后向前复制到 destination 中。由于 destination 初始化为一个递增序列,复制操作会覆盖 destination 中的元素,从后向前替换它们。因此,最终 destination 的内容将是 source 的元素的反向副本。

std::copy_backward 的参数包括:

  • 源序列的开始迭代器(source.begin())
  • 源序列的结束迭代器(source.end())
  • 目标序列的“尾后”迭代器(destination.end()),注意这里不是 destination.begin(),因为 std::copy_backward 是从后向前复制。

请确保目标序列有足够的空间来容纳源序列的元素,否则可能会发生溢出。

需要注意的是,std::copy_backward 在实际使用中并不常见,因为通常情况下我们会使用 std::copy 或 std::copy_n 来从源序列的开始复制到目标序列的开始。std::copy_backward 在某些特定的算法实现中可能会有用,例如在就地(in-place)反转容器时。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

熊猫Devin

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

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

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

打赏作者

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

抵扣说明:

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

余额充值