STL教程(十一):C++ STL常用遍历算法
1、算法概述
算法主要是由头文件,和组成。
是所有STL头文件中最大的一个,其中常用的功能涉及到比较,交换,查找, 遍历,复制,修改,反转,排序,合并等...
体积很小,只包括在几个序列容器上进行的简单运算的模板函数.包括加法乘法在序列上的一些操作。
定义了一些模板类,用以声明函数对象
STL提供了大量实现算法的模版函数,只要我们熟悉了STL之后,许多代码可以被大大的化简,只需要通过调用一两个算法模板,就可以完成所需要的功能,从而大大地提升效率。
2、算法分类
根据操作对象 :
直接改变容器的内容
将原容器的内容复制一份,修改其副本,然后传回该副本
根据功能:
非可变序列算法 指不直接修改其所操作的容器内容的算法
计数算法 count、count_if
搜索算法 search、find、find_if、find_first_of、…
比较算法 equal、mismatch、lexicographical_compare
可变序列算法 指可以修改它们所操作的容器内容的算法
删除算法 remove、remove_if、remove_copy、…
修改算法 for_each、transform
删除算法 remove、remove_if、remove_copy、…、
排序算法 包括对序列进行排序和合并的算法、搜索算法以及有序序列上的集合操作
数值算法 对容器内容进行数值计算
3、常用遍历算法
3.1for_each遍历算法
/*
遍历算法 遍历容器元素
@param beg 开始迭代器
@param end 结束迭代器
@param _callback 函数回调或者函数对象
@return 函数对象
*/
for_each(iterator beg, iterator end, _callback);
使用案例:
//普通函数 void print01(int val){
cout << val << " "; }//函数对象 struct print001{
void operator()(int val)
{
cout << val << " ";
} };//for_each算法基本用法 void test01(){
vector<int> v;
for (int i = 0; i < 10;i++)
{
v.push_back(i);
}
//遍历算法
for_each(v.begin(), v.end(), print01);
cout << endl;
for_each(v.begin(), v.end(), print001());
cout << endl;
}
struct print02{
print02()
{
mCount = 0;
}
void operator()(int val)
{
cout << val << " ";
mCount++;
}
int mCount;
};
//for_each返回值
void test02()
{
vector<int> v;
for (int i = 0; i < 10; i++)
{
v.push_back(i);
}
print02 p = for_each(v.begin(), v.end(), print02());
cout << endl;
cout << p.mCount << endl; }struct print03 : public binary_function<int, int, void>{
void operator()(int val,int bindParam) const
{
cout << val + bindParam << " ";
}
};
//for_each绑定参数输出
void test03(){
vector<int> v;
for (int i = 0; i < 10; i++)
{
v.push_back(i);
}
for_each(v.begin(), v.end(), bind2nd(print03(),100));
}
3.2transform遍历算法
transform: 与for_each类似,遍历所有元素,但可对容器的元素进行修改
作用:
可以一个容器的元素,通过op,变换到另一个容器中(同一个容器中)
也可以把两个容器的元素,通过op,变换到另一个容器中
注意:
1.如果目标与源相同,transform()就和for_each()一样。
2.如果想以某值替换符合规则的元素,应使用replace()算法
/*
transform算法 将指定容器区间元素搬运到另一容器中
注意 : transform 不会给目标容器分配内存,所以需要我们提前分配好内存
@param beg1 源容器开始迭代器
@param end1 源容器结束迭代器
@param beg2 目标容器开始迭代器
@param _cakkback 回调函数或者函数对象
@return 返回目标容器迭代器
*/
transform(iterator beg1, iterator end1, iterator beg2, _callbakc);
使用案例:
struct transformTest01{
int operator()(int val){
return val + 100;
}};struct print01{
void operator()(int val){
cout << val << " ";
}};void test01(){
vector<int> vSource;
for (int i = 0; i < 10;i ++){
vSource.push_back(i + 1);
}
//目标容器
vector<int> vTarget;
//给vTarget开辟空间
vTarget.resize(vSource.size());
//将vSource中的元素搬运到vTarget
vector<int>::iterator it = transform(vSource.begin(), vSource.end(),
vTarget.begin(), transformTest01());
//打印
for_each(vTarget.begin(), vTarget.end(), print01()); cout << endl;
}//将容器1和容器2中的元素相加放入到第三个容器中struct transformTest02{
int operator()(int v1,int v2){
return v1 + v2;
}};void test02(){
vector<int> vSource1;
vector<int> vSource2;
for (int i = 0; i < 10; i++){
vSource1.push_back(i + 1);
}
//目标容器
vector<int> vTarget;
//给vTarget开辟空间
vTarget.resize(vSource1.size());
transform(vSource1.begin(), vSource1.end(),
vSource2.begin(),vTarget.begin(), transformTest02());
//打印
for_each(vTarget.begin(), vTarget.end(), print01()); cout << endl;}
4、for_each()和transform()算法比较
for_each() 速度快 不灵活
transform() 速度慢 非常灵活
for_each所使用的函数对象,参数是引用,没有返回值void mysquare(int &num);
transform所使用的函数对象,参数一般不使用引用,而是还有返回值int mysquare2(int num);
举例:
void mysquare(int &num){
num = num * num;}int mysquare2(int num) //结果的传出,必须是通过返回值{
return num = num * num;}void main_foreach_pk_tranform()
{
vector<int> v1;
v1.push_back(1);
v1.push_back(3);
v1.push_back(5);
vector<int>v2 = v1;
for_each(v1.begin(), v1.end(), mysquare);
printAA(v1);
cout << endl;
transform(v2.begin(), v2.end(), v2.begin(), mysquare2);
printAA(v2);
cout << endl;
}
更多关于智能物联网培训的问题,欢迎咨询千锋教育在线名师。千锋教育拥有多年IT培训服务经验,采用全程面授高品质、高体验培养模式,拥有国内一体化教学管理及学员服务,助力更多学员实现高薪梦想。