STL(一) 算法 for_each、transform

所有的stl算法,想要调用,都需包含头文件#include <algorithm>

for_each

函数原型:for_each (InputIterator beg, InputIterator end, UnaryProc op)

函数功能:对区间[beg,end)中的所有元素执行 op操作。

注意:op操作的返回值会被忽略。
看代码:

using std::for_each;
using std::cout;
using std::endl;
std::list<int> lstForEach;
for (int i = 1; i < 10; ++i)
    lstForEach.push_back(i);

for_each(lstForEach.begin(), lstForEach.end(), [](int i){return i * i; });  //返回值不会对原本的元素产生影响
cout << "返回值: ";
for (auto i : lstForEach)
    cout << i << " ";
cout << endl;

for_each(lstForEach.begin(), lstForEach.end(), [](int& i){i *= i; });  //直接作用于元素本身
cout << "直接作用于元素: ";
for (auto i : lstForEach)
    cout << i << " ";
cout << endl;


      

执行结果:

当然,上面的for_each,完全可以用C++11里面的for循环实现:

        for (auto& i : lstForEach)
            i *= i;

同样简洁得很,所以,C++11后,for_each的用武之地会越来越少。

 

transform

函数原型:OutputIterator transform(InputIterator sourceBeg, InputIterator sourceEnd,
            OutputIterator destBeg, UnaryFunc op)

函数功能:对源区间区间[sourceBeg,sourceEnd)中的所有元素执行 op操作,将返回值作为新的元素,覆盖destBeg开始的目标区间的相应元素。

注意:

1、op操作的返回值作为新的元素放到目标区间,这里的返回值有用;

2、因为是覆盖目标区间的相应元素,所以要保证目标区间有足够的大小;

3、如果想修改源区间本身,可将destBeg设为源区间的起始位置sourceBeg(也可以在op中修改,但如果要这么做,直接用for_each函数即可)。

看代码:

int _tmain(int argc, _TCHAR* argv[])
{
	using std::cout;
	using std::endl;
	std::list<int> lstTransform;
	for (int i = 1; i < 10; ++i)
		lstTransform.push_back(i);
	std::list<int> lstDest(lstTransform.size() + 10, -1);  //这里比lstTransform的size多十个元素
	std::list<int>::iterator iter_return = std::transform(lstTransform.begin(), lstTransform.end(),
		lstDest.begin(), [](int i){return i * i; });//这里的返回值,写到目标区间对应的元素
	cout << "lstDest: ";
	for (int i : lstDest)
		cout << i << " ";
	cout << endl;

	system("pause");
	return 0;
}

执行结果:

还可能会有一种特殊需求:先针对源区间的元素做某操作,再将新的元素做另一个操作写到目标区间。

例如:

有std::list<int>  lstTransform,其中元素是[-10, -1],现在需要将lstTransform中元素平方,再在新的lstTransform中各个元素基础上+10,copy至std::list<int> lstDest中。

方法有很多,可以先for_each对lstTransform中元素平方,再调用transform将元lstTransform中元素+10,copy至lstDest。

也可以直接用transform实现以上两步,代码如下:

int _tmain(int argc, _TCHAR* argv[])
{
	using std::cout;
	using std::endl;

	auto printEle = [](const std::list<int>& lstValue, const std::string& strRemind)  //打印list<int>中元素的lambda表达式
	{
		cout << strRemind;
		for (auto i : lstValue)
			cout << i << " ";
		cout << endl;
	};

	std::list<int> lstTransform;
	for (int i = -10; i < 0; ++i)
		lstTransform.push_back(i);
	printEle(lstTransform, "lstTransform初始数据: ");  //打印原始数据
	std::list<int> lstDest;
	std::transform(lstTransform.begin(), lstTransform.end(),
		std::back_inserter(lstDest),  //这里用的是安插迭代器
		[](int& i){i *= i; return i + 10; });//传入lambda表达式的参数是引用,对于平方后,在将新值+10返回
	printEle(lstTransform, "lstTransform转换后数据:");
	printEle(lstDest, "lstDest数据:");

	system("pause");
	return 0;
}

执行结果:

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值