C++系列-STL中遍历及变换算法


《关山月》唐·李白

明月出天山,苍茫云海间。
长风几万里,吹度玉门关。
汉下白登道,胡窥青海湾。
由来征战地,不见有人还。
戍客望边邑,思归多苦颜。
高楼当此夜,叹息未应闲。


💢什么算法

  • 🔥C++中的算法是通过迭代器和模板来实现的。
  • 🔥简单来说算法就是一系列的计算步骤,用来将输入数据转化成输出结果。

💢算法涉及到的头文件

-🍐 algorithm是STL头文件中最大的一个,范围涉及到比较,交换,查找,遍历,复制,修改等等。
-🍐 numeric体积很小,只包括几个在序列上面进行简单数学运算的模板函数。
-🍐 functional定义了一些模板类,用来声明函数对象。


💢STL中的遍历及变换算法

算法描述
for_each(beg, end, func)将[beg, end)范围内的所有元素一次调用func,返回func的返回值,不修改序列中的元素
transform(beg, end, res, func)将[beg, end)范围内的所有元素一次调用func,结果放入res中,func应该有1个参数,不修改序列中的元素
transform(beg1, end1, beg2, res, func)将[beg1, end1)范围内的所有元素与beg2迭代器指向的容器中的元素做func对应的操作,结果放入res中,不修改序列中的元素,func应该有2个参数,一个为[beg1, end1)指向的内容,一个为beg2为起始指向的内容

💢💢for_each举例

👉 👉 👉
for_each(_InIt _First, _InIt _Last, _Fn _Func)中的3个参数,第一个是起始迭代器,第二个是结束迭代器,第三个是个可以调用的如函数,函数对象,lambda表达式,函数指针等。
示例中分别使用了函数,函数对象,lambda表达式实现func,如果是函数时,后面不能加括号,直接写上函数名即可。
Func中的参数是容器中的元素。

code:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

template<typename T>
void print(T& val)
{
	cout << val << " ";
}

template<class T>
class MyPrint
{
public:
	void operator()(T &val)
	{
		cout << val << " ";
	}
};

void test01()
{
	vector<int> vec1{33, 25, 78, 39, 66};
	// 如果传递的是函数,不用加()
	for_each(vec1.begin(), vec1.end(), print<int>);
	cout << endl;
}

void test02()
{
	vector<int> vec2{55, 11, 56, 43, 25};
	// 如果传递的是函数对象,需要加小括号,这是在创建一个匿名对象
	for_each(vec2.begin(), vec2.end(), MyPrint<int>());
	cout << endl;
}

void test03()
{
	vector<int> vec3{66, 88, 66, 88, 66};
	// 也可以传递lambda表达式或者函数指针等
	for_each(vec3.begin(), vec3.end(), [](int val) -> void {cout << val << " "; });
	cout << endl;
}

void main()
{
	test01();
	test02();
	test03();
	system("pause");
}

result:
33 25 78 39 66
55 11 56 43 25
66 88 66 88 66

💢💢transform举例

👉 👉 👉
transform算法用于对序列中的每个元素应用指定的操作,并将结果存储在另一个序列中。这个算法可以看作是一种投影操作,将一个序列映射到另一个序列。
_OutIt transform(const _InIt _First, const _InIt _Last, _OutIt _Dest, _Fn _Func)中的4个参数说明如下:

参数说明
_First源容器起始迭代器
_Last源容器结束迭代器
_Dest目标容器起始迭代器
_Func可调用的如函数,函数对象,lambda表达式,函数指针等,调用时的一个形参分别传入的是源容器的元素
code:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

template<typename T>
T add10(T& val)
{
	return val+10;
}

template<class T>
class MyMultiply
{
public:
	T operator()(T& val)
	{
		return val*3;
	}
};

template<class T>
class MyPrint
{
public:
	void operator()(T& val)
	{
		cout << val << " ";
	}
};

void test01()
{
	vector<int> vec1{33, 25, 78, 39, 66};
	vector<int> vec2;
	vec2.resize(vec1.size());
	// add10<int>, add10函数的参数是vec1中的元素
	transform(vec1.begin(), vec1.end(), vec2.begin(), add10<int>);
	for_each(vec2.begin(), vec2.end(), MyPrint<int>());
	cout << endl;
}

void test02()
{
	vector<float> vec3{55.5, 11.1, 56.6, 43.3, 25.5, 55.6};
	vector<float> vec4(vec3.size());
	// transform的第4个参数为函数对象
	transform(vec3.begin(), vec3.end(), vec4.begin(), MyMultiply<float>());
	for_each(vec4.begin(), vec4.end(), MyPrint<float>());
	cout << endl;
}

void test03()
{
	vector<int> vec5{1,2,3,4,5};
	vector<int> vec6(vec5.size());
	int (*fun)(int &a) = add10<int>;
	// transform的第4个参数为函数指针
	transform(vec5.begin(), vec5.end(), vec6.begin(), fun);
	for_each(vec6.begin(), vec6.end(), MyPrint<int>());
	cout << endl;
}

void test04()
{
	vector<int> vec7{1, 2, 3, 4, 5};
	vector<int> vec8(vec7.size());
	// 当不想对源容器的元素进行操作时,可以直接返回val
	transform(vec7.begin(), vec7.end(), vec8.begin(), [](int val)-> int {return val;});
	for_each(vec8.begin(), vec8.end(), MyPrint<int>());
	cout << endl;
}

void main()
{
	test01();
	test02();
	test03();
	test04();
	system("pause");
}

result:
43 35 88 49 76
166.5 33.3 169.8 129.9 76.5 166.8
11 12 13 14 15
1 2 3 4 5

👉 👉 👉
_OutIt transform(
const _InIt1 _First1, const _InIt1 _Last1, const _InIt2 _First2, _OutIt _Dest, _Fn _Func)中的5个参数说明如下:

参数说明
_First1第一个容器起始迭代器
_Last1第一个容器结束迭代器
_First2第二个容器结束迭代器
_Dest目标容器起始迭代器
_Func可调用的如函数,函数对象,lambda表达式,函数指针等,调用时的两个形参分别传入的是第一个容器的元素和第二个容器的元素。
code:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

template<typename T>
T add(T& val1, T& val2)
{
	return val1 + val2;
}

template<class T>
class MyMultiply
{
public:
	T operator()(T& val1, T& val2)
	{
		return val1 * val2;
	}
};

template<class T>
class MyPrint
{
public:
	void operator()(T& val)
	{
		cout << val << " ";
	}
};

void test01()
{
	vector<int> vec1{1, 2, 3, 4, 5};
	vector<int> vec2 = vec1;
	vector<int> vec12(vec1.size());
	// add10<int>, add10函数的参数是vec1中的元素
	transform(vec1.begin(), vec1.end(), vec2.begin(), vec12.begin(), add<int>);
	for_each(vec2.begin(), vec2.end(), MyPrint<int>());
	cout << endl;
}

void test02()
{
	vector<float> vec3{1.1, 1.2, 1.3, 1.4, 1.5, 1.6};
	vector<float> vec4 = vec3;
	vector<float> vec34(vec3.size());
	// transform的第4个参数为函数对象
	transform(vec3.begin(), vec3.end(), vec4.begin(), vec34.begin(), MyMultiply<float>());
	for_each(vec34.begin(), vec34.end(), MyPrint<float>());
	cout << endl;
}

void main()
{
	test01();
	test02();
	system("pause");
}

result:
1 2 3 4 5
1.21 1.44 1.69 1.96 2.25 2.56
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值