文章目录
0 STL算法
STL算法主要由<algorithm>
<functional>
<numeric>
等头文件组成。
<algorithm>
:包括遍历、查找、排序、比较、交换、复制、修改等操作的函数模板。
<functional>
:包括函数对象/仿函数相关的类模板。
<numeric>
:体积较小,仅包括简单数学运算相关的函数模板。
1 常用遍历算法【for_each、transform】
算法简介:
for_each
:遍历容器元素及统一逻辑处理。
transform
:将源容器的元素全部拷贝至目标容器。
1.1 for_each【遍历容器元素及统一逻辑处理】
作用:遍历容器元素及统一逻辑处理。
注:使用
for_each
算法时,需包含头文件include <algorithm>
。
函数原型:
for_each(iterator begin, iterator end, _func);
参数解释:
begin
:迭代器起始位置;
end
:迭代器结束位置;
_func
:对当前所遍历的容器元素的处理。
①普通回调函数;
②函数对象/仿函数;
③匿名函数(lambda表达式)。
示例:
#include <iostream>
using namespace std;
#include <vector>
#include <algorithm> //使用for_each算法
//普通回调函数
void print(int val) {
cout << val << " ";
}
//函数对象/仿函数
class Printer{
public:
void operator()(int val) {
cout << val << " ";
}
};
int main() {
vector<int> v;
v.push_back(9);
v.push_back(1);
v.push_back(7);
v.push_back(6);
v.push_back(3);
/* 遍历容器元素 */
//1.for_each算法 + 普通回调函数————传递函数名
for_each(v.begin(), v.end(), print); //9 1 7 6 3
//2.for_each算法 + 函数对象/仿函数————传递匿名函数对象
for_each(v.begin(), v.end(), Printer()); //9 1 7 6 3
//3.for_each算法 + 匿名函数(lambda表达式)
for_each(v.begin(), v.end(), [](int val) {cout << val << " "; }); //9 1 7 6 3
/* 对容器元素的统一逻辑处理 */
//全部容器元素的值减1后输出
for_each(v.begin(), v.end(), [](int val) {cout << val - 1 << " "; }); //8 0 6 5 2
return 0;
}
1.2 transform【将源容器的元素全部拷贝至目标容器】
作用:将源容器的元素全部拷贝至目标容器。
注1:使用
transform
算法时,需包含头文件include <algorithm>
。
注2:使用transform
算法时,需为目标容器提前开辟内存空间,如dest.resize(src.size());
,否则程序运行时崩溃。
函数原型:
transform(iterator begin1, iterator end1, iterator begin2, _func);
参数解释:
begin1
:源容器迭代器起始位置;
end1
:源容器迭代器结束位置;
begin2
:目标容器迭代器起始位置;
_func
:对当前遍历容器元素的逻辑运算处理。
①普通回调函数;
②函数对象/仿函数;
③匿名函数(lambda表达式)。
示例:
#include <iostream>
using namespace std;
#include <vector>
#include <algorithm> //使用transform算法
//普通回调函数
int print(int val) {
//元素值加10
return val + 10;
}
//函数对象/仿函数
class Printer {
public:
int operator()(int val) {
//直接返回元素
return val;
}
};
int main() {
vector<int> src;
for(int i = 0; i < 5; i++){
src.push_back(i);
}
/* 拷贝容器的全部元素,必须为目标容器提前开辟内存空间 */
vector<int> dest;
dest.resize(src.size());
//1.transform算法 + 普通回调函数————传递函数名
transform(src.begin(), src.end(), dest.begin(), print);
for_each(dest.begin(), dest.end(), [](int val) {cout << val << " "; }); //10 11 12 13 14
//2.transform算法 + 函数对象/仿函数————传递匿名函数对象
transform(src.begin(), src.end(), dest.begin(), Printer());
for_each(dest.begin(), dest.end(), [](int val) {cout << val << " "; }); //0 1 2 3 4
//3.transform算法 + 匿名函数(lambda表达式)
transform(src.begin(), src.end(), dest.begin(), [](int val) {return val + 20; });
for_each(dest.begin(), dest.end(), [](int val) {cout << val << " "; }); //20 21 22 23 24
return 0;
}
2 常用查找算法【find、find_if、adjacent_find、binary_search、count、count_if】
算法简介:
find
:查找指定元素是否存在。
find_if
:按条件查找元素是否存在。
adjacent_find
:查找相邻且重复的元素。
binary_search
:二分查找判断元素是否存在。
count
:统计元素个数。
count_if
:按条件统计元素个数。
2.1 find【查找指定元素是否存在】
作用:查找指定元素是否存在:存在则返回第1次匹配指定元素的迭代器位置;不存在则返回结束迭代器end()
。
注1:使用
find
算法时,需包含头文件include <algorithm>
。
注2:查找自定义数据类型的元素时,需在自定义数据类型的类中,重载运算符operator==
,告知find
算法应如何比较两个自定义数据类型的对象。
函数原型:
find(iterator begin, iterator end, value);
参数解释:
begin
:迭代器起始位置;
end
:迭代器结束位置;
value
:待查找的元素。
示例:
#include <iostream>
using namespace std;
#include <vector>
#include <algorithm> //使用find算法
//查找内置数据类型元素
void func1() {
vector<int> v;
v.push_back(9);
v.push_back(1);
v.push_back(7);
v.push_back(6);
v.push_back(3);
vector<int>::iterator pos = find(v.begin(), v.end(), 6);
if (pos != v.end()) {
cout << "目标元素存在:" << *pos << endl; //6
}
else {
cout << "目标元素不存在.." << endl;
}
}
class Person {
public:
string name;
int age;
Person(string name, int age) {
this->name = name;
this->age = age;
}
//重载operator==运算符
bool operator==(const Person& p) {
return this->name == p.name && this->age == p.age;
}
};
//查找自定义数据类型元素,需重载operator==运算符
void func2() {
vector<Person> v;
Person p1("Tom", 16);
Person p2("Jerry", 18);
Person p3("Jack", 20);
Person p4("Lucy", 22);
v.push_back(p1);
v.push_back(p2);
v.push_back(p3);
v.push_back(p4);
Person person("Lucy", 22);
vector<Person>::iterator pos = find(v.begin(), v.end(), person);
if (pos != v.end()) {
cout << "目标元素存在:" << endl;
cout << "姓名:" << (*pos).name << ",年龄:" << pos->age << endl;
}
else {
cout << "目标元素不存在.." << endl;
}
}
int main() {
func1();
func2();
return 0;
}
2.2 find_if【按条件查找元素是否存在】
作用:按条件查找元素是否存在:存在则返回第1次匹配指定条件的迭代器位置;不存在则返回结束迭代器end()
。
注1:使用
find_if
算法时,需包含头文件include <algorithm>
。
注2:查找自定义数据类型的元素时,需指定查询条件:①普通回调函数;②谓词(返回类型为bool
的仿函数);③匿名函数(lambda表达式)。
注3:按值查询使用find
,按条件查询使用find_if
。
函数原型:
find_if(iterator begin, iterator end, _Pred);
参数解释:
begin
:迭代器起始位置;
end
:迭代器结束位置;
_Pred
:指定查询的条件。
①普通回调函数;
②谓词(返回类型为bool
的仿函数);
③匿名函数(lambda表达式)。
示例:
#include <iostream>
using namespace std;
#include <vector>
#include <algorithm> //使用find_if算法
//回调函数
bool lessThanFive(int val) {
return val < 5;
}
//谓词(返回类型为bool的仿函数/函数对象)
class LessThanFive {
public:
bool operator()(int val) {
return val < 5;
}
};
//查找内置数据类型元素
void func1() {
vector<int> v;
v.push_back(9);
v.push_back(1);
v.push_back(7);
v.push_back(6);
v.push_back(3);
//回调函数
//vector<int>::iterator pos = find_if(v.begin(), v.end(), lessThanFive);
//谓词
//vector<int>::iterator pos = find_if(v.begin(), v.end(), LessThanFive());
//匿名函数(lambda表达式)
vector<int>::iterator pos = find_if(v.begin(), v.end(), [](int val) {return val < 5;});
if (pos != v.end()) {
cout << "目标元素存在:" << *pos << endl; //1
}
else {
cout << "目标元素不存在.." << endl;
}
}
class Person {
public:
string name;
int age;
Person(string name, int age) {
this->name = name;
this->age = age;
}
};
//回调函数
bool greaterThan20(const Person &p) {
return p.age > 20;
}
//谓词(返回类型为bool的仿函数/函数对象)
class GreaterThan20 {
public:
bool operator()(const Person& p) {
return p.age > 20;
}
};
//查找自定义数据类型元素,需重载operator==运算符
void func2() {
vector<Person> v;
Person p1("Tom", 16);
Person p2("Jerry", 18);
Person p3("Jack", 20);
Person p4("Lucy", 22);
v.push_back(p1);
v.push_back(p2);
v.push_back(p3);
v.push_back(p4);
//回调函数
//vector<Person>::iterator pos = find_if(v.begin(), v.end(), greaterThan20);
//谓词
//vector<Person>::iterator pos = find_if(v.begin(), v.end(), GreaterThan20());
//匿名函数(lambda表达式)
vector<Person>::iterator pos = find_if(v.begin(), v.end(), [](const Person &p) {return p.age > 20; });
if (pos != v.end()) {
cout << "目标元素存在:" << endl;
cout << "姓名:" << (*pos).name << ",年龄:" << pos->age << endl; //姓名:Lucy,年龄:22
}
else {
cout << "目标元素不存在.." << endl;
}
}
int main() {
//func1();
func2();
return 0;
}
2.3 adjacent_find【查找相邻且重复的元素】
作用:查找相邻且重复的元素是否存在:存在则返回相邻且重复元素中第1个元素的迭代器位置;不存在则返回结束迭代器end()
。
函数原型:
adjacent_find(iterator begin, iterator end);
参数解释:
begin
:迭代器起始位置;
end
:迭代器结束位置。
示例:
#include <iostream>
using namespace std;
#include <vector>
#include <algorithm> //使用adjacent_find算法
//查找相邻且重复元素
void func1() {
vector<int> v;
v.push_back(9); //重复元素,但不相邻
v.push_back(1);
v.push_back(9);
v.push_back(7);
v.push_back(6);
v.push_back(3); //相邻且重复元素
v.push_back(3);
//adjacent_find算法
vector<int>::iterator pos = adjacent_find(v.begin(), v.end());
if (pos != v.end()) {
cout << "存在相邻且重复元素:" << *pos << endl; //3
}
else {
cout << "不存在相邻且重复元素.." << endl;
}
}
int main() {
func1();
return 0;
}
2.4 binary_search【二分查找法判断指定元素是否存在】
作用:二分查找法判断指定元素是否存在:存在则返回true
;不存在则返回false
。
注1:
binary_search
算法的查找效率高,但必须对有序序列使用,无序序列中不可用。
注2:使用binary_search
算法时,需包含头文件include <algorithm>
。
函数原型:
bool binary_search(iterator begin, iterator end, value);
参数解释:
begin
:迭代器起始位置;
end
:迭代器结束位置;
value
:待查找的元素。
示例:
#include <iostream>
using namespace std;
#include <vector>
#include <algorithm> //使用binary_search算法
//对有序序列使用二分查找
int main() {
vector<int> v;
v.push_back(9);
v.push_back(1);
v.push_back(7);
v.push_back(6);
v.push_back(3);
//只能对有序序列使用二分查找
sort(v.begin(), v.end());
bool flag = binary_search(v.begin(), v.end(), 6);
cout << (flag ? "存在" : "不存在") << endl; //存在
return 0;
}
2.5 count【统计指定元素的个数】
作用:统计指定元素的个数。
注1:使用
count
算法时,需包含头文件include <algorithm>
。
注2:统计自定义数据类型元素的个数时,需在自定义数据类型的类中,重载运算符operator==
,告知count
算法应如何比较两个自定义数据类型的对象。
函数原型:
count(iterator begin, iterator end, value);
参数解释:
begin
:迭代器起始位置;
end
:迭代器结束位置;
value
:待查找的元素。
示例:
#include <iostream>
using namespace std;
#include <vector>
#include <algorithm> //使用count算法
//统计内置数据类型元素的个数
void func1() {
vector<int> v;
v.push_back(9);
v.push_back(1);
v.push_back(1);
v.push_back(1);
v.push_back(7);
v.push_back(6);
v.push_back(3);
int total = count(v.begin(), v.end(), 1);
cout << "元素1的个数:" << total << endl; //3
}
class Person {
public:
string name;
int age;
Person(string name, int age) {
this->name = name;
this->age = age;
}
//重载operator==运算符
//与目标对象age属性相等
bool operator==(const Person& p) {
return this->age == p.age;
}
};
//统计自定义数据类型元素的个数
void func2() {
vector<Person> v;
Person p1("Tom", 16);
Person p2("Jerry", 18);
Person p3("Jack", 22);
Person p4("Lucy", 22);
v.push_back(p1);
v.push_back(p2);
v.push_back(p3);
v.push_back(p4);
Person person("Michael", 22);
int total = count(v.begin(), v.end(), person);
cout << "与Michael同龄的Person对象个数:" << total << endl; //2
}
int main() {
func1();
func2();
return 0;
}
2.6 count_if【按条件统计指定元素的个数】
作用:按条件统计指定元素的个数。
注1:使用
count_if
算法时,需包含头文件include <algorithm>
。
注2:按值统计使用count
,按条件统计使用count_if
。
函数原型:
count_if(iterator begin, iterator end, _Pred);
参数解释:
begin
:迭代器起始位置;
end
:迭代器结束位置;
_Pred
:指定统计的条件。
①普通回调函数;
②谓词(返回类型为bool
的仿函数);
③匿名函数(lambda表达式)。
示例:
#include <iostream>
using namespace std;
#include <vector>
#include <algorithm> //使用count_if算法
//回调函数
bool lessThanFive(int val) {
return val < 5;
}
//谓词(返回类型为bool的仿函数/函数对象)
class LessThanFive {
public:
bool operator()(int val) {
return val < 5;
}
};
//按条件统计内置数据类型元素的个数
void func1() {
vector<int> v;
v.push_back(9);
v.push_back(1);
v.push_back(7);
v.push_back(6);
v.push_back(3);
/* 统计值小于5的元素 */
//回调函数
//int total = count_if(v.begin(), v.end(), lessThanFive);
//谓词
//int total = count_if(v.begin(), v.end(), LessThanFive());
//匿名函数(lambda表达式)
int total = count_if(v.begin(), v.end(), [](int val) {return val < 5; });
cout << "值小于5的元素个数:" << total << endl; //2
}
class Person {
public:
string name;
int age;
Person(string name, int age) {
this->name = name;
this->age = age;
}
};
//回调函数
bool ageGreaterThan20(const Person& p) {
return p.age > 20;
}
//谓词(返回类型为bool的仿函数/函数对象)
class AgeGreaterThan20 {
public:
bool operator()(const Person& p) {
return p.age > 20;
}
};
//按条件统计自定义数据类型元素的个数
void func2() {
vector<Person> v;
Person p1("Tom", 16);
Person p2("Jerry", 18);
Person p3("Jack", 20);
Person p4("Lucy", 22);
v.push_back(p1);
v.push_back(p2);
v.push_back(p3);
v.push_back(p4);
//回调函数
//int total = count_if(v.begin(), v.end(), ageGreaterThan20);
//谓词
//int total = count_if(v.begin(), v.end(), AgeGreaterThan20());
//匿名函数(lambda表达式)
int total = count_if(v.begin(), v.end(), [](const Person& p) {return p.age > 20; });
cout << "年龄大于20的Person对象个数:" << total << endl; //1
}
int main() {
//func1();
func2();
return 0;
}
3 常用排序算法【sort、random_shuffle、merge、reverse】
算法简介:
sort
:对容器元素排序。
random_shuffle
:对指定范围的容器元素随机排序,即洗牌。
merge
:合并两个容器的元素,并存储至新容器中。
reverse
:反转的容器元素。
3.1 sort【对容器元素排序】
作用:对容器元素排序。
注:使用
sort
算法时,需包含头文件include <algorithm>
。
函数原型:
sort(iterator begin, iterator end, _Pred);
参数解释:
begin
:迭代器起始位置;
end
:迭代器结束位置;
_Pred
:可选项,默认升序排序;可指定自定义排序规则。
①普通回调函数;
②谓词(返回类型为bool
的仿函数);
③匿名函数(lambda表达式)。
④内建函数对象/关系仿函数(bool greater<T>
或bool less<T>
)。
示例:
#include <iostream>
using namespace std;
#include <vector>
#include <algorithm> //使用sort算法
//回调函数
bool myCompare(int val1, int val2) {
return val1 > val2;
}
//函数对象/仿函数
class MyCompare {
public:
//重载函数调用运算符()
bool operator()(int val1, int val2) {
return val1 > val2;
}
};
//sort排序
int main() {
vector<int> v;
v.push_back(9);
v.push_back(1);
v.push_back(7);
v.push_back(6);
v.push_back(3);
//默认升序排序
sort(v.begin(), v.end());
for_each(v.begin(), v.end(), [](int val) {cout << val << " "; }); //1 3 6 7 9
/* 降序排序 */
//1.回调函数实现降序排序
sort(v.begin(), v.end(), myCompare);
for_each(v.begin(), v.end(), [](int val) {cout << val << " "; }); //9 7 6 3 1
//2.仿函数实现降序排序
sort(v.begin(), v.end(), MyCompare());
for_each(v.begin(), v.end(), [](int val) {cout << val << " "; }); //9 7 6 3 1
//3.匿名函数(lambda表达式)实现降序排序
sort(v.begin(), v.end(), [](int val1, int val2) {return val1 > val2; });
for_each(v.begin(), v.end(), [](int val) {cout << val << " "; }); //9 7 6 3 1
//4.内建函数对象实现降序排序
sort(v.begin(), v.end(), greater<int>());
for_each(v.begin(), v.end(), [](int val) {cout << val << " "; }); //9 7 6 3 1
return 0;
}
3.2 random_shuffle【洗牌:对指定范围的容器元素随机排序】
作用:对指定范围的容器元素随机排序,即洗牌。
注1:使用
random_shuffle
算法时,需包含头文件include <algorithm>
。
注2:为保证随机性,需包含头文件include <ctime>
,添加随机数种子srand((unsigned int)time(NULL));
。
函数原型:
random_shuffle(iterator begin, iterator end);
参数解释:
begin
:迭代器起始位置;
end
:迭代器结束位置;
示例:
#include <iostream>
using namespace std;
#include <vector>
#include <algorithm> //使用sort算法
#include <ctime> //添加随机数种子
int main() {
//添加随机数种子
srand((unsigned int)time(NULL));
vector<int> v;
for (int i = 0; i < 10; i++) {
v.push_back(i);
}
//0 1 2 3 4 5 6 7 8 9
for_each(v.begin(), v.end(), [](int val) {cout << val << " "; });
//洗牌算法
random_shuffle(v.begin(), v.end());
//随机排序:6 9 1 4 3 2 0 5 7 8
for_each(v.begin(), v.end(), [](int val) {cout << val << " "; });
return 0;
}
3.3 merge【合并两个容器的元素,并存储至新容器中】
作用:合并两个容器的元素,并存储至新容器中。
注1:使用
merge
算法时,需包含头文件include <algorithm>
。
注2:使用merge
算法时,两个源容器的元素必须有序且顺序一致,合并后,新容器中的元素仍有序。
注3:使用merge
算法时,需为目标容器提前开辟内存空间,如dest.resize(src1.size() + src2.size());
,否则程序运行时崩溃。
函数原型:
merge(iterator begin1, iterator end1, iterator begin2, iterator end2, iterator dest);
参数解释:
begin1
:源容器1迭代器的起始位置;
end1
:源容器1迭代器的结束位置;
begin2
:源容器2迭代器的起始位置;
end2
:源容器2迭代器的结束位置;
dest
:目标容器迭代器的起始位置。
示例:
#include <iostream>
using namespace std;
#include <vector>
#include <algorithm> //使用merge算法
int main() {
//合并的两个源容器必须有序,且顺序一致
vector<int> src1;
for (int i = 0; i < 5; i++) {
src1.push_back(i);
}
vector<int> src2;
for (int i = 5; i < 10; i++) {
src2.push_back(i);
}
//合并前,需为目标容器提前分配内存空间
vector<int> dest;
dest.resize(src1.size() + src2.size());
//merge合并
merge(src1.begin(), src1.end(), src2.begin(), src2.end(), dest.begin());
//0 1 2 3 4 5 6 7 8 9
for_each(dest.begin(), dest.end(), [](int val) {cout << val << " "; });
return 0;
}
3.4 reverse【反转容器元素】
作用:反转容器元素。
注:使用
reverse
算法时,需包含头文件include <algorithm>
。
函数原型:
reverse(iterator begin, iterator end);
参数解释:
begin
:迭代器起始位置;
end
:迭代器结束位置;
示例:
#include <iostream>
using namespace std;
#include <vector>
#include <algorithm> //使用reverse算法
int main() {
vector<int> v;
v.push_back(9);
v.push_back(1);
v.push_back(7);
v.push_back(6);
v.push_back(3);
for_each(v.begin(), v.end(), [](int val) {cout << val << " "; }); //9 1 7 6 3
//反转容器的元素
reverse(v.begin(), v.end());
for_each(v.begin(), v.end(), [](int val) {cout << val << " "; }); //3 6 7 1 9
return 0;
}
4 常用拷贝【copy】和替换【replace、replace_if、swap】算法
算法简介:
copy
:拷贝容器元素至另一容器。
replace
:将容器内的指定值全部替换为新值。
replace_if
:按条件将容器内指定范围的旧元素替换为新元素。
swap
:互换两个相同类型容器的元素。
4.1 copy【拷贝容器元素至另一容器】
作用:拷贝容器元素至另一容器。
注1:使用
copy
算法时,需包含头文件include <algorithm>
。
注2:使用copy
算法时,需为目标容器提前开辟内存空间,如dest.resize(src.size());
,否则程序运行时崩溃。
函数原型:
copy(iterator begin, iterator end, iterator dest);
参数解释:
begin
:源容器迭代器的起始位置;
end
:源容器迭代器的结束位置;
dest
:目标容器迭代器的起始位置。
注:实际开发时,
copy
算法应用较少,建议使用容器的赋值操作。
示例:
#include <iostream>
using namespace std;
#include <vector>
#include <algorithm> //使用copy算法
int main() {
vector<int> src;
for (int i = 0; i < 5; i++) {
src.push_back(i);
}
for_each(src.begin(), src.end(), [](int val) {cout << val << " "; }); //0 1 2 3 4
//copy算法拷贝元素时,需为目标容器提前开辟内存空间
vector<int> dest;
dest.resize(src.size());
//copy
copy(src.begin(), src.end(), dest.begin());
for_each(dest.begin(), dest.end(), [](int val) {cout << val << " "; }); //0 1 2 3 4
return 0;
}
4.2 replace【将指定值全部替换为新值】
作用:将容器内的指定值的元素全部替换为新值。
注:使用
replace
算法时,需包含头文件include <algorithm>
。
函数原型:
replace(iterator begin, iterator end, oldvalue, newvalue);
参数解释:
begin
:迭代器起始位置;
end
:迭代器结束位置;
oldvalue
:被替换的旧元素;
oldvalue
:替换的新元素。
示例:
#include <iostream>
using namespace std;
#include <vector>
#include <algorithm> //使用replace算法
int main() {
vector<int> v;
v.push_back(9);
v.push_back(7);
v.push_back(1);
v.push_back(7);
v.push_back(6);
v.push_back(7);
v.push_back(3);
for_each(v.begin(), v.end(), [](int val) {cout << val << " "; }); //9 7 1 7 6 7 3
//replace():将容器内的指定值全部替换为新值
replace(v.begin(), v.end(), 7, 0);
for_each(v.begin(), v.end(), [](int val) {cout << val << " "; }); //9 0 1 0 6 0 3
return 0;
}
4.3 replace_if【将满足指定条件的元素全部替换为新元素】
作用:将容器内满足指定条件的元素全部替换为新元素。
注:使用
replace_if
算法时,需包含头文件include <algorithm>
。
函数原型:
replace_if(iterator begin, iterator end, _pred, newvalue);
参数解释:
begin
:迭代器起始位置;
end
:迭代器结束位置;
_pred
:指定条件。
①普通回调函数;
②谓词(返回类型为bool
的仿函数);
③匿名函数(lambda表达式)。
newvalue
:替换的新元素。
示例:
#include <iostream>
using namespace std;
#include <vector>
#include <algorithm> //使用replace_if算法
//回调函数
bool lessThanFive(int val) {
return val < 5;
}
//谓词(返回类型为bool的仿函数/函数对象)
class LessThanFive {
public:
bool operator()(int val) {
return val < 5;
}
};
//将小于5的元素全部替换为100
int main() {
vector<int> v;
v.push_back(9);
v.push_back(1);
v.push_back(7);
v.push_back(6);
v.push_back(3);
for_each(v.begin(), v.end(), [](int val) {cout << val << " "; }); //9 1 7 6 3
//回调函数
//replace_if(v.begin(), v.end(), lessThanFive, 100);
//for_each(v.begin(), v.end(), [](int val) {cout << val << " "; }); //9 100 7 6 100
//谓词
//replace_if(v.begin(), v.end(), LessThanFive(), 100);
//for_each(v.begin(), v.end(), [](int val) {cout << val << " "; }); //9 100 7 6 100
//匿名函数(lambda表达式)
replace_if(v.begin(), v.end(), [](int val) {return val < 5; }, 100);
for_each(v.begin(), v.end(), [](int val) {cout << val << " "; }); //9 100 7 6 100
return 0;
}
4.4 swap【互换两个同类型容器的元素】
作用:互换两个相同类型容器的元素。
注:使用
swap
算法时,需包含头文件include <algorithm>
。
函数原型:
swap(container c1, container c2);
参数解释:
c1
:容器1;
c2
:容器2。
示例:
#include <iostream>
using namespace std;
#include <vector>
#include <algorithm> //使用swap算法
int main() {
vector<int> v1;
vector<int> v2;
for (int i = 0; i < 5; i++) {
v1.push_back(i);
v2.push_back(-i);
}
cout << "交换前..." << endl;
for_each(v1.begin(), v1.end(), [](int val) {cout << val << " "; }); //0 1 2 3 4
cout << endl;
for_each(v2.begin(), v2.end(), [](int val) {cout << val << " "; }); //0 -1 -2 -3 -4
cout << endl;
//交换
swap(v1, v2);
cout << "交换后..." << endl;
for_each(v1.begin(), v1.end(), [](int val) {cout << val << " "; }); //0 -1 -2 -3 -4
cout << endl;
for_each(v2.begin(), v2.end(), [](int val) {cout << val << " "; }); //0 1 2 3 4
cout << endl;
return 0;
}
5 常用算术生成算法【accumulate、fill】
算法简介:
accumulate
:计算容器指定区间内元素的累和。
fill
:向容器填充指定元素。
注:算术生成算法属于小型算法,使用时需包含头文件
#include <numeric>
。
5.1 accumulate【计算容器元素的累和】
作用:计算容器指定区间内元素的累和。
注:使用
accumulate
算法时,需包含头文件include <numeric>
。
函数原型:
accumulate(iterator begin, iterator end, value);
参数解释:
begin
:迭代器起始位置;
end
:迭代器结束位置;
value
:起始累加值。
示例:
#include <iostream>
using namespace std;
#include <vector>
#include <numeric> //使用accumulate算法
#include <algorithm> //使用for_each算法
int main() {
vector<int> v;
v.push_back(9);
v.push_back(1);
v.push_back(7);
v.push_back(6);
v.push_back(3);
//计算元素累和(起始累加值设置为0)
int sum = accumulate(v.begin(), v.end(), 0);
cout << "sum = " << sum << endl; //26
return 0;
}
5.2 fill【向容器填充指定元素】
作用:向容器填充指定元素。
注:使用
fill
算法时,需包含头文件include <numeric>
。
函数原型:
fill(iterator begin, iterator end, value);
参数解释:
begin
:迭代器起始位置;
end
:迭代器结束位置;
value
:填充的指定值。
示例:
#include <iostream>
using namespace std;
#include <vector>
#include <numeric> //使用fill算法
#include <algorithm> //使用for_each算法
int main() {
vector<int> v;
v.resize(5); //使用默认值0填充
for_each(v.begin(), v.end(), [](int val) {cout << val << " "; }); //0 0 0 0 0
//fill():向容器中填充指定元素
fill(v.begin(), v.end(), 6);
for_each(v.begin(), v.end(), [](int val) {cout << val << " "; }); //6 6 6 6 6
return 0;
}
6 常用集合算法【set_intersection、set_union、set_difference】
算法简介:
set_intersection
:将两个容器的交集存储至新容器。
set_union
:将两个容器的并集存储至新容器。
set_difference
:将两个容器的差集存储至新容器。
6.1 set_intersection【将两个容器的交集存储至新容器】
作用:将两个容器的交集存储至新容器,并返回交集中最后1个元素的迭代器位置。
注1:使用
set_intersection
算法时,需包含头文件include <algorithm>
。
注2:使用set_intersection
算法时,需为目标容器提前开辟内存空间,交集元素个数至多为两容器大小的较小值
,如dest.resize( min(src1.size(), src2.size()) );
,否则程序运行时崩溃。
注3:使用set_intersection
算法时,两个源容器的元素必须有序且顺序一致,否则程序运行时崩溃。合并后,新容器中的元素仍有序。
注4:遍历新容器时,迭代器结束位置需使用交集的最后1个元素的迭代器位置,而不能使用新容器的结束迭代器,否则可能出现多余的填充值0
。
函数原型:
set_intersection(iterator begin1, iterator end1, iterator begin2, iterator end2, iterator dest);
参数解释:
begin1
:源容器1迭代器的起始位置;
end1
:源容器1迭代器的结束位置;
begin2
:源容器2迭代器的起始位置;
end2
:源容器2迭代器的结束位置;
dest
:目标容器迭代器的起始位置。
示例:
#include <iostream>
using namespace std;
#include <vector>
#include <algorithm> //使用set_intersection算法
int main() {
//合并的两个源容器必须有序,且顺序一致,否则程序运行时崩溃
vector<int> src1;
for (int i = 0; i < 5; i++) {
src1.push_back(i); //0 1 2 3 4
}
vector<int> src2;
for (int i = 3; i < 8; i++) {
src2.push_back(i); //3 4 5 6 7
}
//合并前,需为目标容器提前分配内存空间
vector<int> dest;
//交集元素个数至多为两容器大小的较小值
dest.resize(min(src1.size(), src2.size()));
//求两容器元素的交集,返回交集最后1个元素的迭代器位置last
vector<int>::iterator last = set_intersection(src1.begin(), src1.end(), src2.begin(), src2.end(), dest.begin());
//遍历新容器时,迭代器结束位置需使用【交集】的最后1个元素的迭代器位置last
for_each(dest.begin(), last, [](int val) {cout << val << " "; }); //3 4
//不能使用新容器的结束迭代器dest.end(),否则可能出现多余的填充值0
//dest容器大小为5个,交集元素共2个,多余3个填充0值
//for_each(dest.begin(), dest.end(), [](int val) {cout << val << " "; }); //3 4 0 0 0
return 0;
}
6.2 set_union【将两个容器的并集存储至新容器】
作用:将两个容器的并集存储至新容器,并返回并集中最后1个元素的迭代器位置。
注1:使用
set_union
算法时,需包含头文件include <algorithm>
。
注2:使用set_union
算法时,需为目标容器提前开辟内存空间,并集元素个数至多为两容器大小的总和
,如dest.resize(src1.size() + src2.size());
,否则程序运行时崩溃。
注3:使用set_union
算法时,两个源容器的元素必须有序且顺序一致,否则程序运行时崩溃。合并后,新容器中的元素仍有序。
注4:遍历新容器时,迭代器结束位置需使用并集的最后1个元素的迭代器位置,而不能使用新容器的结束迭代器,否则可能出现多余的填充值0
。
函数原型:
set_union(iterator begin1, iterator end1, iterator begin2, iterator end2, iterator dest);
参数解释:
begin1
:源容器1迭代器的起始位置;
end1
:源容器1迭代器的结束位置;
begin2
:源容器2迭代器的起始位置;
end2
:源容器2迭代器的结束位置;
dest
:目标容器迭代器的起始位置。
示例:
#include <iostream>
using namespace std;
#include <vector>
#include <algorithm> //使用set_union算法
int main() {
//合并的两个源容器必须有序,且顺序一致,否则程序运行时崩溃
vector<int> src1;
for (int i = 0; i < 5; i++) {
src1.push_back(i); //0 1 2 3 4
}
vector<int> src2;
for (int i = 3; i < 8; i++) {
src2.push_back(i); //3 4 5 6 7
}
//合并前,需为目标容器提前分配内存空间
vector<int> dest;
//并集元素个数至多为两容器大小的总和
dest.resize(src1.size() + src2.size());
//求两容器元素的并集,返回并集最后1个元素的迭代器位置last
vector<int>::iterator last = set_union(src1.begin(), src1.end(), src2.begin(), src2.end(), dest.begin());
//遍历新容器时,迭代器结束位置需使用【并集】的最后1个元素的迭代器位置last
for_each(dest.begin(), last, [](int val) {cout << val << " "; }); //0 1 2 3 4 5 6 7
//不能使用新容器的结束迭代器dest.end(),否则可能出现多余的填充值0
//dest容器大小为10个,并集元素共8个,多余2个填充0值
//for_each(dest.begin(), dest.end(), [](int val) {cout << val << " "; }); //0 1 2 3 4 5 6 7 0 0
return 0;
}
6.3 set_difference【将两个容器的差集存储至新容器】
作用:将两个容器的差集存储至新容器,并返回差集中最后1个元素的迭代器位置。
注1:使用
set_difference
算法时,需包含头文件include <algorithm>
。
注2:使用set_difference
算法时,需为目标容器提前开辟内存空间,差集元素个数至多为两容器大小的较大值
,如dest.resize( max(src1.size(), src2.size()) );
,否则程序运行时崩溃。
注3:使用set_difference
算法时,两个源容器的元素必须有序且顺序一致,否则程序运行时崩溃。合并后,新容器中的元素仍有序。
注4:遍历新容器时,迭代器结束位置需使用差集的最后1个元素的迭代器位置,而不能使用新容器的结束迭代器,否则可能出现多余的填充值0
。
函数原型:
set_difference(iterator begin1, iterator end1, iterator begin2, iterator end2, iterator dest);
参数解释:
begin1
:源容器1迭代器的起始位置;
end1
:源容器1迭代器的结束位置;
begin2
:源容器2迭代器的起始位置;
end2
:源容器2迭代器的结束位置;
dest
:目标容器迭代器的起始位置。
示例:
#include <iostream>
using namespace std;
#include <vector>
#include <algorithm> //使用set_difference算法
int main() {
//合并的两个源容器必须有序,且顺序一致,否则程序运行时崩溃
vector<int> src1;
for (int i = 0; i < 5; i++) {
src1.push_back(i); //0 1 2 3 4
}
vector<int> src2;
for (int i = 3; i < 8; i++) {
src2.push_back(i); //3 4 5 6 7
}
//合并前,需为目标容器提前分配内存空间
vector<int> dest;
//差集元素个数至多为两容器大小的较大值
dest.resize(max(src1.size(), src2.size()));
cout << "容器src1与容器src2的差集:" << endl;
//求两容器元素的差集,返回差集最后1个元素的迭代器位置last
vector<int>::iterator last = set_difference(src1.begin(), src1.end(), src2.begin(), src2.end(), dest.begin());
//遍历新容器时,迭代器结束位置需使用【差集】的最后1个元素的迭代器位置last
for_each(dest.begin(), last, [](int val) {cout << val << " "; }); //0 1 2
cout << endl;
//不能使用新容器的结束迭代器dest.end(),否则可能出现多余的填充值0
//dest容器大小为5个,差集元素共3个,多余2个填充0值
//for_each(dest.begin(), dest.end(), [](int val) {cout << val << " "; }); //0 1 2 0 0
cout << "容器src2与容器src1的差集:" << endl;
last = set_difference(src2.begin(), src2.end(), src1.begin(), src1.end(), dest.begin());
//遍历新容器时,迭代器结束位置需使用【差集】的最后1个元素的迭代器位置last
for_each(dest.begin(), last, [](int val) {cout << val << " "; }); //5 6 7
cout << endl;
//不能使用新容器的结束迭代器dest.end(),否则可能出现多余的填充值0
//dest容器大小为5个,差集元素共3个,多余2个填充0值
//for_each(dest.begin(), dest.end(), [](int val) {cout << val << " "; }); //5 6 7 0 0
return 0;
}