目录
前言
在使用STL算法时需要包含有关头文件。主要是由头文件<algorithm> <functional> <numeric>组成。
1. <algorithm>是所有STL头文件中最大的一个,范围涉及到比较、交换、查找、遍历操作、复制、修改等等
2. <numeric>体积很小,只包括几个在序列上面进行简单数学运算的模板函数
3. <functional>定义了一些模板类,用以声明函数对象
一、常用的遍历算法
遍历算法语法:
for each //遍历容器
transform //搬运容器到另一个容器中
1.1 for_each
功能描述:实现遍历容器
函数原型: for each(iterator beg, iterator end, func); // 遍历算法 遍历容元素
下面为使用普通函数遍历和使用仿函数遍历的方法。需要注意的是在使用普通函数时,在for_each() 中不加(),因为要传递的是函数的地址(即为函数指针)。在使用仿函数时,需要加(),传入的是一个匿名对象类。
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
//常用遍历算法 for_each
//1.普通函数
void print(int a)
{
cout << a << " ";
}
//仿函数
class print2
{
public:
void operator()(int a)
{
cout << a << " ";
}
};
void test01()
{
vector<int>v;
for (int i = 0; i < 10; i++)
{
v.push_back(i);
}
for_each(v.begin(), v.end(), print);//这里print 不加() 因为这里传递的是函数的地址(函数指针)
cout << endl;
for_each(v.begin(), v.end(), print2());//这里加() 仿函数是一个类加()是传入一个匿名对象类
}
int main()
{
test01();
system("pause");
return 0;
}
1.2 transform
transform(iterator beg1, iterator end1, iterator beg2,_func);
需要注意:搬运的目标容器必须要提前开辟空间,用 resize() 指定容器的容量,否则无法正常搬运。
二、常见的查找算法
查找算法语法:
1. find //查找元素
2. find_if //按条件查找元素
3. adjacent_find //查找相邻重复元素
4. binary_search //二分查找法
5. count //统计元素个数
6. count_if //按条件统计元素个数
2.1 find()
find() 功能概述:查找指定元素,找到返回指定元素的迭代器,找不到返回结束迭代器end()
函数原型: find(iterator beg, iterator end, value) ;
当自定义数据类型时,使用 find() 函数前需要重载 “==” 号。下面为一个自定义类,在使用 find()查找时,需要在 person 类中利用布尔类型重载“==”号,其中传入的参数需要用const声明,防止值被修改。代码如下所示:
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
class person
{
public:
person(string name, int age)
{
this->m_name = name;
this->m_age = age;
}
//重载 == 让底层find知道如何对比person数据类型
bool operator==(const person &p1)
{
if (this->m_name == p1.m_name && this->m_age == p1.m_age)
{
return true;
}
else
{
return false;
}
}
string m_name;
int m_age;
};
void test01()
{
vector<person>v;
person p1("张三", 10);
person p2("李四", 20);
person p3("王五", 30);
person p4("赵六", 40);
v.push_back(p1);
v.push_back(p2);
v.push_back(p3);
v.push_back(p4);
vector<person>::iterator it = find(v.begin(), v.end(), p2);
if (it == v.end())
{
cout << "没有找到" << endl;
}
else
{
cout << "找到了,姓名:" << it->m_name << " 年龄:" << (*it).m_age << endl;
}
}
int main()
{
test01();
return 0;
}
2.2 find_if
功能描述:按条件查找元素
函数原型: find if(iterator beg, iterator end, Pred); // 按值查找元素,找到返回指定位置迭代器,找不到返回结束迭代器位置
beg: 开始选代器;end: 结束选代器;_Pred: 函数或者谓词 (返回bool类型的仿函数)
2.3 adjacent_find
功能描述: 查找相邻重复元素
函数原型: adjacent_find(iterator beg, iterator end ) ; //查找相邻重复元素,返回相邻元素的第一个位置的迭代器
2.4 binary_search
功能描述: 查找指定元素是否存在
函数原型: bool binary_search(iterator beg, iterator end, value) ; //查找指定的元素,查到返回true否则false
注意: 在无序序列中不可用
2.5 count_if
功能描述: 按条件统计元素个数
函数原型: count_if(iterator beg, iterator end,_Pred ) ; // 按条件统计元素出现次数
三、常用的排序算法
算法简介:
1. sort //对容器内元素进行排序
2. random_shuffle //洗牌 指定范围内的元素随机调整次序
3. merge //容器元素合并,并存储到另一容器中
4. reverse //反转指定范围的元素
下面介绍 random_shuffle 洗牌排序算法、merge 合并排序算法和 reverse 反转排序算法 。
3.1 random_shuffle洗牌算法
洗牌算法:指定范围内的元素随机调整次序
下面为演示代码:
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<ctime>
//常用的排序算法 rand_shuffle
void test01()
{
vector<int>v;
for (int i = 0; i < 10; i++)
{
v.push_back(i);
}
//利用洗牌算法打乱顺序
random_shuffle(v.begin(), v.end());
for (vector<int>::iterator it = v.begin();it != v.end();it++)
{
cout << *it << " ";
}
cout << endl;
}
int main()
{
srand((unsigned int)time(NULL));//加入随机种子
test01();
return 0;
}
运行结果如下:
9 7 6 8 2 4 1 3 5 0
3.2 merge
功能描述: 两个容器元素合并,并存储到另—容器中
函数原型: merge(iterator beg1,iterator end1, iterator beg2,iterator end2, iterator dest); //容器元素合并,并存储到另一容器中
注意: 两个容器必须是有序的。
下面为演示代码:
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
//常用排序算法 merge
void print(int val)
{
cout << val << " ";
}
void test01()
{
vector<int>v;
vector<int>v2;
for (int i = 0; i < 10; i++)
{
v.push_back(i);
v2.push_back(i+1);
}
//将V、V2合并放入新目标容器
vector<int>vtarget;
vtarget.resize(v.size()+v2.size());//目标容器提前开辟空间
merge(v.begin(), v.end(), v2.begin(), v2.end(), vtarget.begin());
for_each(vtarget.begin(), vtarget.end(), print);
cout << endl;
}
int main()
{
test01();
return 0;
}
运行结果如下:
0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10
3.3 reverse 反转排序算法
功能描述: 将容器内元素进行反转
函数原型: reverse(iterator beg,iterator end) ; // 反转指定范围的元素
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
//常用排序算法 reverse
void print(int val)
{
cout << val << " ";
}
void test01()
{
vector<int>v;
v.push_back(0);
v.push_back(3);
v.push_back(5);
v.push_back(0);
v.push_back(4);
cout << "反转前" << endl;
for_each(v.begin(), v.end(), print);
cout << endl;
cout << "反转后" << endl;
reverse(v.begin(), v.end());
for_each(v.begin(), v.end(), print);
cout << endl;
}
int main()
{
test01();
return 0;
}
运行结果如下:
反转前
0 3 5 0 4
反转后
4 0 5 3 0
四、常用拷贝和替换算法
算法简介:
1. copy //容器内指定范围的元素拷贝到另—容器中
2. replace //将容器内指定范围的所有旧元素替换为新元素
3. replace_if //容器内指定范围所有满足条件的元素替换为新元素
4. swap //互换两个容器的元素(必须为同种类型)
五、常用算术生成算法
注意: 算术生成算法属于小型算法,使用时包含的头文件为 #include <numeric>
算法简介:
accumulate //计算容器元素累计总和
fill // 向容器中添加元素
5.1 accumulate
计算区间内容器元素累计总和
函数原型: accumulate(iterator beg, iterator end, value); //计算容器元素累计总和
其中参数3 value 为累加的起始值(例如val=100,则累加前数值为100,要在100的基础上累加上去)。
5.2 fill
功能描述:向容器中填充指定的元素
函数原型:fill ( iterator beg, iterator end, value); // 向容器中填充元素
其中参数3 value 为填充的值
六、常用的集合算法
算法简介:
1. set_intersection // 求两个容器的交集
2. set_union // 求两个容器的并集
3. set_difference // 求两个容器的差集
6.1 set_intersection 交集
下面为演示代码:
#include<iostream>
using namespace std;
#include<vector>
#include<numeric>
#include<algorithm>
//常见的集合算法 set_intersection
void print(int val)
{
cout << val << " ";
}
void test01()
{
vector<int>v1;
vector<int>v2;
for (int i = 0; i < 10; i++)
{
v1.push_back(i);
v2.push_back(i+5);
}
vector<int>v3;
//目标容器提前开辟空间
v3.resize(min(v1.size(), v2.size()));
//获取交集
vector<int>::iterator it=set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), v3.begin());
for_each(v3.begin(), it, print);//结束不用end()迭代器,用it
}
int main()
{
test01();
return 0;
}
运行结果如下:
5 6 7 8 9
注意: 两个容器必须为有序序列
6.2 set_union 并集
语法:set_union(iterator beg1,iterator end1,iterator beg2,iterator end2,iterator dest);
set_union 的用法与 set_intersection 的一致,需要注意的是这里的容器容量应改为:v3.resize(v1.size()+v2.size());
注意: 两个容器必须为有序序列
6.3 set_difference 差集
函数原型: set_difference(iterator beg1,iterator end1,iterator beg2,iterator end2,iterator dest);
下面为演示代码:
#include<iostream>
using namespace std;
#include<vector>
#include<numeric>
#include<algorithm>
//常见的集合算法 set_difference
void print(int val)
{
cout << val << " ";
}
void test01()
{
vector<int>v1;
vector<int>v2;
for (int i = 0; i < 10; i++)
{
v1.push_back(i);
v2.push_back(i + 5);
}
vector<int>v3;
//目标容器提前开辟空间
v3.resize(max(v1.size(), v2.size()));
//获取v1对v2的差集
cout << "v1对v2的差集" << endl;
vector<int>::iterator it = set_difference(v1.begin(), v1.end(), v2.begin(), v2.end(), v3.begin());
for_each(v3.begin(), it, print);//结束不用end()迭代器,用it
cout << endl;
cout << "v2对v1的差集" << endl;
it = set_difference(v2.begin(), v2.end(), v1.begin(), v1.end(), v3.begin());
for_each(v3.begin(), it, print);//结束不用end()迭代器,用it
cout << endl;
}
int main()
{
test01();
return 0;
}
运行结果如下:
v1对v2的差集
0 1 2 3 4
v2对v1的差集
10 11 12 13 14
注意: 两个容器必须为有序序列