📜  C++ STL-algorithm.transform()函数(1)

📅  最后修改于: 2023-12-03 14:39:50.720000             🧑  作者: Mango

C++ STL-algorithm.transform()函数

简介

transform()函数是C++ STL中的一个高阶函数(higher-order function),它可以将一个序列(sequence)中的每个元素依次经过某个函数变换,生成一个新的序列。

transform()函数定义在头文件<algorithm>中,可以处理不同种类的容器类型,如vectorlistarray等,它的原型如下:

template<class InputIt1, class InputIt2, class OutputIt, class BinaryOperation>
OutputIt transform(InputIt1 first1, InputIt1 last1, InputIt2 first2, OutputIt d_first, BinaryOperation binary_op);

其中,

  • first1last1指定了输入序列的范围;
  • first2指定了第二个输入序列(如果需要的话)的起始位置;
  • d_first指定了输出序列的起始位置;
  • binary_op是一个接收两个参数的函数对象,用于对输入序列中对应的元素做转换操作。

transform()函数有很多应用场景,常见的用法有:

  • 将一种类型的容器转换为另一种类型的容器;
  • 对容器中的元素做一些简单的操作;
  • 多个序列的元素经过相应的函数变换后,生成一个新的序列。

下面将通过几个具体的示例来介绍这个函数的使用方法。

示例
例1 - 简单变换

首先,我们考虑一个简单的例子,将一个数字序列中的每个元素都加1。

#include <iostream>
#include <vector>
#include <algorithm>

int plus_one(int x) {
    return x + 1;
}

int main() {
    std::vector<int> nums{1, 2, 3};

    std::vector<int> res(nums.size());
    std::transform(nums.begin(), nums.end(), res.begin(), plus_one);

    std::cout << "Input:  ";
    for (int x : nums) {
        std::cout << x << " ";
    }
    std::cout << std::endl;

    std::cout << "Output: ";
    for (int x : res) {
        std::cout << x << " ";
    }
    std::cout << std::endl;

    return 0;
}

输出结果为:

Input:  1 2 3 
Output: 2 3 4 

这个例子中,我们定义了一个加1的函数plus_one(),并将它传递给transform()函数作为转换函数。由于输入和输出序列都是vector类型,因此我们使用了vector<int>作为容器类型。

transform()函数的第三个参数res.begin()指定了输出序列的起始位置,它是一个迭代器(iterator),表明函数的返回值是一个迭代器类型。

例2 - 两个序列的操作

接下来,我们考虑一个稍微复杂一些的例子,假设有两个长度相同的序列A和B,我们要将它们对应位置的元素相加,并将结果放到新的序列C中。

#include <iostream>
#include <vector>
#include <algorithm>

int add(int x, int y) {
    return x + y;
}

int main() {
    std::vector<int> A{1, 2, 3};
    std::vector<int> B{4, 5, 6};

    std::vector<int> C(A.size());
    std::transform(A.begin(), A.end(), B.begin(), C.begin(), add);

    std::cout << "A: ";
    for (int x : A) {
        std::cout << x << " ";
    }
    std::cout << std::endl;

    std::cout << "B: ";
    for (int x : B) {
        std::cout << x << " ";
    }
    std::cout << std::endl;

    std::cout << "C: ";
    for (int x : C) {
        std::cout << x << " ";
    }
    std::cout << std::endl;

    return 0;
}

输出结果为:

A: 1 2 3 
B: 4 5 6 
C: 5 7 9 

这个例子中,我们定义了一个加法函数add(),并调用transform()函数对两个序列进行操作。由于两个输入和一个输出序列都是vector类型,因此我们使用了vector<int>作为容器类型。

transform()函数的前4个参数分别是两个输入序列和一个输出序列的起始和终止位置,最后一个参数是函数对象,它接受两个参数并返回一个结果。

例3 - 转换容器类型

最后,我们来看一个将一个vector容器转换成set容器的例子。假设有一个包含若干字符串的vector容器,我们要将它传递给一个函数,并把所有的字符串插入到一个set容器中。

#include <iostream>
#include <vector>
#include <set>
#include <algorithm>

void insert_to_set(const std::vector<std::string>& v, std::set<std::string>& s) {
    std::transform(v.begin(), v.end(), std::inserter(s, s.begin()), [](const std::string& x) {
        return x;
    });
}

int main() {
    std::vector<std::string> v{"apple", "pear", "banana"};

    std::set<std::string> s;
    insert_to_set(v, s);

    std::cout << "Input:  ";
    for (const std::string& x : v) {
        std::cout << x << " ";
    }
    std::cout << std::endl;

    std::cout << "Output: ";
    for (const std::string& x : s) {
        std::cout << x << " ";
    }
    std::cout << std::endl;

    return 0;
}

输出结果为:

Input:  apple pear banana 
Output: apple banana pear 

这个例子中,我们定义了一个函数insert_to_set(),它接受一个vector容器和一个set容器,将vector中的所有元素插入到set中。

我们使用了inserter函数来将元素逐个插入到set容器中,这里需要将std::inserter()作为第三个参数传递给transform()函数。

注意的是,我们在匿名函数中直接返回了元素本身,这是因为insert_to_set()函数需要对容器中的每个元素做复制操作,因此我们直接返回元素本身即可。