欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 锐评 > C++系列-STL中遍历及变换算法

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

2024/10/24 16:22:26 来源:https://blog.csdn.net/weixin_48668114/article/details/142187647  浏览:    关键词:C++系列-STL中遍历及变换算法

STL中常用算法

  • 💢什么算法
  • 💢算法涉及到的头文件
  • 💢STL中的遍历及变换算法
    • 💢💢for_each举例
    • 💢💢transform举例


《关山月》唐·李白

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


💢什么算法

  • 🔥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());// 当不想对源容器的元素进行操作时,可以直接返回valtransform(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

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com