概述:
- 使用算法记得包含头文件等
- 是所有STL头文件中最大的一个,范围涉及到比较、交换、查找、遍历、复制、修改等
- 体积很小,只包括几个在序列上面进行简单数学运算的模板函数
- 定义了一些模板类,用以声明函数对象
一、常用遍历算法
1、for_each:
实现遍历容器:
for_each(iterator beg, iterator end, _func);
//分别用普通函数与函数对象来作为第三个参数
//普通函数
void print01(int val)
{
cout << val << endl;
}
//仿函数
class Print02
{
public:
void operator()(int val)
{
cout << val << " ";
}
};
void test01()
{
vector<int>v;
for (int i = 0; i < 10; i++)
{
v.push_back(i);
}
for_each(v.begin(), v.end(), print01);
for_each(v.begin(), v.end(), Print02());
}
2、transform
transform搬运容器到另一个容器中
transform(iterator beg1. iterator end1, iterator beg2, _func)
//四个参数分别为源容器开始迭代器、源容器结束迭代器、目标容器开始迭代器与函数或函数对象
二、常用查找算法
算法简介:
find //查找元素
find_if //按条件查找元素
adjacent_find //查找相邻重复元素
binary_search //二分查找法
count //统计元素个数
count_if //按条件统计元素个数
1、find
查找指定元素,找到返回指定元素的迭代器,找不到返回结束迭代器end()
find(iterator beg, iterator end, value);
//查找内置数据类型
void test01()
{
vector<int>v;
for (int i = 0; i < 10; i++)
{
v.push_back(i);
}
//查找容器中是否有 5 这个元素
vector<int>::iterator it = find(v.begin(), v.end(), 5);
if (it == v.end())
{
cout << "没有找到!" << endl;
}
else
{
cout << "找到了!" << *it << endl;
}
}
class Person
{
public:
Person(string name, int age)
{
this->m_Age = age;
this->m_Name = name;
}
//重载 == 让低层的find知道如何对比Person
bool operator==(const Person & p)
{
if (this->m_Age == p.m_Age && this->m_Name == p.m_Name)
{
return true;
}
else
{
return false;
}
}
string m_Name;
int m_Age;
};
//查找自定义数据类型
void test02()
{
vector<Person>v;
//创建数据
Person p1("aaa", 10);
Person p2("bbb", 20);
Person p3("ccc", 30);
Person p4("ddd", 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;
}
}
总结:查找自定义数据类型时,find底层中的==号不知道该如何对比,因此需要重载运算符。
2、find_if
按条件查找元素
find_if(iterator beg, iterator end, _Pred);
//按值查找元素,找到返回指定位置迭代器,找不到返回结束迭代器位置,_Pred为谓词
3、adjacent_find
查找相邻重复元素
函数原型:
adjacent_find(iterator beg, iterator end);
//查找相邻重复元素,返回相邻元素的第一个位置的迭代器
4、binary_search
查找指定元素是否存在
函数原型:
bool binary_search(iterator beg, iterator end, value);
//查找指定的元素,查到返回true,否则返回false
注意:在无序序列中不可用!
5、count
统计元素个数
count(iterator beg, iterator end, value)
//统计元素出现次数
6、count_if
count_if(iterator beg, iterator end, _Pred)
//按条件统计元素出现次数
三、常用排序算法
常用排序算法:
- sort 对容器内元素进行排序
- random_shuffle 打乱
- merge 容器元素合并,并存储到另一容器中
- reverse 反转指定范围的元素
1、sort
sort(iterator beg, iterator end, _Pred);
//按值查找元素,找到返回指定位置迭代器,找不到返回结束迭代器位置
前面已经介绍过
2、random_shuffle
random_shuffle(iterator beg, iterator end);
//指定范围内的元素随机调整次序
只需传入开始迭代器和结束迭代器,十分简单。
3、merge
merge(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
//容器元素合并,并存储到另一容器中
//注意:两个容器必须是有序的!
//dest为目标容器开始迭代器
4、reverse
reverse(iterator beg, iterator end);
//反转指定范围内的元素
四、常用拷贝和替换算法
copy //容器内指定范围的元素拷贝到另一容器中
replace //将容器内指定范围的旧元素修改为新元素
replace_if //容器内指定范围满足条件的元素替换为新元素
swap //互换两个容器的元素
unique //删除相邻重复项
1、copy
copy(iterator beg, iterator end, iterator dest);
//把beg到end的元素拷贝给dest所属的容器
//dest为目标起始迭代器
2、replace
replace(iterator beg, iterator end, oldvalue, newvalue)
//将区间内的旧元素,替换为新元素
3、replace_if
replace_if(iterator beg, iterator end, _Pred, newvalue)
//按条件替换元素,满足条件的替换成指定元素
//函数对象做条件,筛选大于等于30的元素,替换成newvalue
class Greater30
{
public:
bool operator()(int val)
{
return val >= 30;
}
}
4、swap
swap(container c1, container c2);
//互换两个容器的元素
5、unique
unique(iterator beg, iterator end);
//重排序列,删除重复项,返回一个指向不重复值范围末尾的迭代器。
五、常用算术生成、删除算法
算术生成算法属于小型算法,使用时包含的头文件为 #include
注意:算法不会执行容器操作,因此它们自身不可能改变容器大小。必须确保序列原大小不小于我们要求算法写入的元素数目。
accumulate //计算容器元素累计总和
fill //向容器中添加元素
fill_n //向容器中添加元素
erase //删除容器中元素
1、accumulate
accumulate(iterator beg, iterator end, value)
//计算区间内容器元素累计总和
2、fill
fill(iterator beg, iterator end, value);
//向容器中填充元素(后期重新填充)
3、fill_n
fill_n(dest, n, val);
//从迭代器dest开始,之后的n个元素都赋值为val。需要后面至少有n个元素的位置。
4、erase
erase(iterator beg, iterator end);
//删除指定范围内元素,即使首尾迭代器重复也不会报错。
但当我们想通过算法改变容器大小、进行赋值操作时,可以借用一个特殊的迭代器:插入迭代器(insert iterator),它主要通过调用back_inserter函数实现。
vector<int> vec;
auto it = back_inserter(vec);
*it = xx;
//插入迭代器接受一个指向容器的引用,返回一个与该容器绑定的插入迭代器
fill_n(back_inserter(vec), 10, 0);
//添加10个0到vec容器的末尾,其本质相当于vec调用push_back函数。
六、常用集合算法
set_intersection //求两个容器的交集
set_union //求两个容器的并集
set_difference //求两个容器的差集
1、set_intersection
set_intersection(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
//求两个集合的交集,两个集合必须是有序序列
//dest为目标容器开始迭代器
注意:找到的交集需要存在另一个容器中,目标容器需要提前开辟空间。如果是大容器包含小容器,开辟空间取小容器的size即可。
2、set_union
set_union(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
//求两个集合的并集,两个集合必须是有序序列
3、set_difference
set_difference(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
//求两个集合的差集,两个集合必须是有序序列