0
点赞
收藏
分享

微信扫一扫

c++ STL变换算法:transfrom()详解

变换主要函数有:

  • transform() :将某操作应用于指定范围的每个元素。

transform函数模板的行为等效于:

template <class InputIterator, class OutputIterator, class UnaryOperator>
  OutputIterator transform (InputIterator first1, InputIterator last1,
                            OutputIterator result, UnaryOperator op)
{
  while (first1 != last1) {
    *result = op(*first1);  // or: *result=binary_op(*first1,*first2++);
    ++result; ++first1;
  }
  return result;
}

可以将函数应用到序列的元素上,并将这个函数返回的值保存到另一个序列中,它返回的迭代器指向输出序列所保存的最后一个元素的下一个位置。

例子:

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

using namespace std;
int func1(int value){
    return value * 2;
}
int main() {
    int a[5] = {1, 2, 3, 4, 5};
    vector<int> v1(a, a+ 5);
    vector<int> v2(5);  //初始有5个int大小
    cout<< "原始向量v1 = ";
    copy(v1.begin(), v1.end(), ostream_iterator<int>(cout, " "));
    cout<< endl;
    cout<< "v1 * 2 --> v1 = ";
    transform(v1.begin(), v1.end(), v1.begin(), func1);//调用一元函数
    copy(v1.begin(), v1.end(), ostream_iterator<int>(cout, " "));
    cout<< endl;
    return 0;
}

c++ STL变换算法:transfrom()详解_变换算法

在这里第三个参数指向输入容器的元素的迭代器。调用func1函数将value乘2,第三个参数是输入序列的开始迭代器,应用第 4 个参数指定的函数的结果会被存回它所运用的元素上。

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

using namespace std;
int func2(int value1, int value2){
    return value1 + value2;
}
int main() {
    int a2[5] = {1, 2, 3, 4, 5};
    int b2[5] = {6, 7, 8, 9, 10};
    int c2[5];
    cout<< "a2[5] = ";
    copy(a2, a2 + 5, ostream_iterator<int>(cout, " "));
    cout<< endl;
    cout<< "b2[5] = ";
    copy(b2, b2 + 5, ostream_iterator<int>(cout, " "));
    cout<< endl;
    cout<< "a2 + b2 --> c2 = ";
    transform(a2, a2 + 5, b2, c2, func2);   //调用二元函数
    copy(c2, c2 + 5, ostream_iterator<int>(cout, " "));
    return 0;
}

c++ STL变换算法:transfrom()详解_STL库_02

二元函数模板:

  • 前两个参数是第一个输入序列的输入迭代器。
  • 第3个参数是第二个输入序列的开始迭代器,显然,这个序列必须至少包含和第一个输入序列同样多的元素。
  • 第4个参数是一个序列的输出迭代器,它所指向的是用来保存应用函数后得到的结果的序列的开始迭代器。
  • 第5个参数是一个函数对象,它定义了一个接受两个参数的函数,这个函数接受来自两个输入序列中的元素作为参数,返回一个可以保存在输出序列中的值。

transform函数分为一元和二元两个模板,上文演示了transform 如何调用一元函数及二元函数。结果可以修改自己,如transform(v1l.begin(),vl. end(),v1. begin(),funcl);也可以形成新的集合,如transform(v1.begin(),v1.end(),v2.begin(),func1)。为了避免初始容器大小的冲突,可以通过加back_inserter解决,如transform (v1.begin(), v1.end(), back_inserter(v), func1);

既然调用的是一元或二元函数,我们可以结合STL中提供的系统函数对象。如transform(v1. begin(),v1.end(),v2.begin(),func1)可以修改为transform(v1.begin(),v1.end(),v2.begin(),bind2nd(multiplies≤int>(),2 ));如transform(a2,a2+5,b2,c2,func2)可以修改为transform(a2,a2+5,b2,c2,plus())。当然,不要忘记加包含文件#include 。

根据transform的功能,我们可以写一个字符串加密程序:

#include <iostream>
#include <fstream>
#include <string>
#include <string>
#include <vector>
#include <iterator>
#include <algorithm>
#include <functional>
using namespace std;

template<class T>
class Encrypt {

};
template<>  //模板特化
class Encrypt<string> {
public:
    string operator()(const string& src) {
        string s;
        for_each(src.begin(), src.end(), [&s](char c) {
            c = c + 1;
            s.push_back(c);
            });
        return s;
    }
};

int main() {
    string strText;
    vector<string> v;
    vector<string> vResult;
    ifstream in("d:\\b.txt");   //内容为: Hello World!
    while (!in.eof()) {
        getline(in, strText, '\n');
        v.push_back(strText);
    }
    in.close();
    transform(v.begin(), v.end(), back_inserter(vResult), Encrypt<string>());
    copy(vResult.begin(), vResult.end(), ostream_iterator<string>(cout, " "));
    return 0;
}

c++ STL变换算法:transfrom()详解_算法_03

在函数对象类Encrypt中,将字符串中对应字符ASCII 加1即是加密结果。当然我们也可以将Encrypt类转换为lambda函数:

transform(v.begin(), v.end(), back_inserter(vResult), [](const string& src) {
        string s;
        for_each(src.begin(), src.end(), [&s](char c) {
            c = c + 1;
            s.push_back(c);
            });
        return s;
        });

举报

相关推荐

0 条评论