c++ STL算法与应用(二) 转换序列transform

 transform可以将函数应用于序列的元素上,并将返回值保存到另一个序列,返回值为输出序列保存的最后一个元素的下一个位置。和for_each的区别在于

    1、for_each函数返回值必须为void,可以通过参数修改原序列的值

    2、transform的二元函数必须返回一个值,同时也能将结果保存到另一个序列

    3、transform中输出序列中的元素类型可以和输入序列中的元素类型不同 

    4、transform可以有两个输入序列,支持二元函数

   以下为代码示例,不多说了 

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

int main() {
#ifdef USE1
	std::vector<double> deg_C{ 21.0,30.5,0.0,3.2,100.0 };
	std::vector<double> deg_F(deg_C.size());
	std::transform(deg_C.begin(), deg_C.end(), deg_F.begin(), [](double temp) {return 32.0 + 9.0 * temp / 5.0; }); //用begin的话要确保容器能装下所有元素
	std::copy(deg_F.begin(), deg_F.end(), std::ostream_iterator<double>(std::cout, " "));
	std::cout << std::endl;
	std::cout << "--------------------------" << std::endl;
#elif defined USE2
	std::vector<double> deg_C{ 21.0,30.5,0.0,3.2,100.0 };
	std::vector<double> deg_F;
	std::transform(deg_C.begin(), deg_C.end(), std::back_inserter(deg_F), [](double temp) {return 32.0 + 9.0 *temp / 5.0; }); //用back_inserter的话会在容器后面插入
	std::copy(deg_F.begin(), deg_F.end(), std::ostream_iterator<double>(std::cout, " "));
	std::cout << std::endl;
	std::cout << "--------------------------" << std::endl;
#elif defined USE3  //处理完序列中的每个元素可以放到不同类型的另一个序列中,但是transform中的处理函数的返回类型必须和目标容器元素类型一致
	std::vector<std::string> deg_C{"one","two","three","four","five"};
	std::vector<size_t> deg_F;
	std::transform(deg_C.begin(), deg_C.end(), std::back_inserter(deg_F), std::hash<std::string>()); //std::hash<T>()为定义在std::string中的一个hash函数对象
	std::copy(deg_F.begin(), deg_F.end(), std::ostream_iterator<double>(std::cout, " "));
	std::cout << std::endl;
	std::cout << "--------------------------" << std::endl;
#elif defined USE4 //可以在transform所运用的函数中调用一个算法
	std::deque<std::string> names{ "Stan Laurel", "Oliver Hardy", "Harold Lloyd" };
	std::transform(names.begin(), names.end(), names.begin(), [](std::string& s) {std::transform(s.begin(), s.end(), s.begin(), ::toupper); return s; });
	std::for_each(names.begin(), names.end(), [](std::string &s) {std::cout << s.data() << " "; });
	std::cout << std::endl;
	std::cout << "--------------------------" << std::endl;
#else //可以用两个输入序列做为输入序列
	//计算正六边形的周长
	using Point = std::pair<double, double>;
	std::vector<Point> hexagon{ {1,2},{2,1},{3,1},{4,2},{3,3},{2,3},{1,2} }; //取前6个点做为第一个输入序列,后6个点做为第二个输入序列
	std::vector<double> segments;
	std::transform(hexagon.begin(), hexagon.end() - 1, hexagon.begin() + 1, std::back_inserter(segments),//第三个参数为第二个输入序列的开始迭代器,该序列元素个数至少等于第一个输入序列
		[](Point &p1, Point &p2) {return std::sqrt((p1.first - p2.first)*(p1.first - p2.first) + (p1.second - p2.second) * (p1.second - p2.second)); });
	std::copy(segments.begin(), segments.end(), std::ostream_iterator<double>(std::cout, " "));
	std::cout << std::endl;
	std::cout << std::accumulate(segments.begin(), segments.end(), 0.0) << std::endl;
#endif // DEBUG
	return 0;
}

猜你喜欢

转载自blog.csdn.net/wanghualin033/article/details/81436114