一、引言
※本文记录一些C++常用的算法,用于简单使用※
- 一般要使用C++的内置算法,需要包含以下三个头文件:
#include<algorithm>、#include<functional>、#include<numeric>
| 头文件 | 解释 |
| #include<algorithm> | algorithm是STL头文件中最大的一个, 涉及:比较交换、查找、遍历、修改、复制等操作。 |
| #include<functional> | 定义了一些函数模板,用于仿函数 |
| #include<numeric> | 体积很小,仅仅包括几个在序列上进行简单数学运算的函数模板 |
二、常用遍历算法
2.1 for_each
for_each会遍历整个容器,它的使用方法如下所示:
| 声明 | 解释 |
| for_each(iterator begin, iterator end, 仿函数或函数); | (使用前,记得包含头文 #include<algorithm>)
|
下面用一个小示例来具体说明如何使用for_each函数:
//函数
void printInt(int elem) {
cout << elem << " ";
}
//仿函数
class PrintInt {
public:
void operator()(int elem) const {
cout << elem << " ";
}
};
//主函数
int main() {
vector<int> v0;
for (int i = 0; i < 5; i++) {
v0.push_back(i);
}//v0 = 0 1 2 3 4
//第三个参数为仿函数
PrintInt print_int;
cout << "第三个参数是仿函数:" << endl;
for_each(v0.begin(), v0.end(), print_int);
cout << endl;
//第三个参数为函数
cout << "第三个参数是函数:" << endl;
for_each(v0.begin(), v0.end(), printInt);
cout << endl;
return 0;
}
程序的执行结果如下所示:

2.2 transform
transform会将一个容器的全部元素复制到另一个容器中,它的函数声明如下所示:
※注意※:在使用之前,一定要先让目标容器使用resize(源容器.size())先设置其容量!!。
| 声明 | 解释 |
| transform(iterator begin1, iterator end1, iterator begin2, 仿函数或函数); |
(使用前,记得包含头文 #include<algorithm>)
|
下面用一个小示例来具体说明如何使用transform函数:
//输出函数
void printInt(int elem) {
cout << elem << " ";
}
//函数:值+1
int changeInt(int elem) {
elem++;
return elem;
}
//仿函数:值-1
class ChangeInt {
public:
int operator()(int i) {
i--;
return i;
}
};
int main() {
vector<int> v0;//源容器
vector<int> v1;//目标容器:第四个参数使用函数
vector<int> v2;//目标容器:第四个参数使用仿函数
for (int i = 0; i < 5; i++) {
v0.push_back(i);
}//v0 = 0 1 2 3 4
//输出v0
cout << "v0 : [";
for_each(v0.begin(), v0.end(), printInt);
cout << "]" << endl;
//输出v1
cout << "v1 : [";
for_each(v1.begin(), v1.end(), printInt);
cout << "]" << endl;
//输出v2
cout << "v2 : [";
for_each(v2.begin(), v2.end(), printInt);
cout << "]" << endl;
//使用transform函数:第四个参数使用函数
v1.resize(v0.size());
transform(v0.begin(), v0.end(), v1.begin(), changeInt);
//使用transform函数:第四个参数使用仿函数
v2.resize(v0.size());
ChangeInt change;
transform(v0.begin(), v0.end(), v2.begin(), change);
//输出v0
cout << "v0 : [";
for_each(v0.begin(), v0.end(), printInt);
cout << "]" << endl;
//输出v1
cout << "v1 : [";
for_each(v1.begin(), v1.end(), printInt);
cout << "]" << endl;
//输出v2
cout << "v2 : [";
for_each(v2.begin(), v2.end(), printInt);
cout << "]" << endl;
return 0;
}
以上例子,将第四个参数设置为函数,将v0的每个值+1后,搬运给v1;
将第四个参数设置为仿函数,将v0的每个值-1后,搬运给v2,程序执行结果如下:

三、常用查找算法
3.0 注意
针对自定义类型的查找算法:在比较过程中,其实程序并不知道如何比较两个元素是否相等,也就是没有对应的==运算符。因此,我们需要在自定义类中重载==运算符
(下文中只在find和find_if中做示例说明,此外的其余函数均同理)
※ binary_search只能用于有序序列!※
3.1 find
find用于查找容器中的指定元素。
如果找到,则返回元素的迭代器;如果没找到,则返回本容器的结束迭代器end()。声明如下:
| 声明 | 解释 |
| find(iterator begin, iterator end, value); | (使用前,记得包含头文 #include<algorithm>)
|
3.1.1 内置类型元素的find
vector<int> v0;
for (int i = 0; i < 10; i++) {
v0.push_back(i);
}//v0 = 0 1 2 3 4 5 6 7 8 9
vector<int>::iterator it4 = find(v0.begin(), v0.end(), 4);
cout << "find 4 : " << boolalpha << (*it4 == 4) << endl;
vector<int>::iterator it11 = find(v0.begin(), v0.end(), 11);
cout << "find 11 : " << boolalpha << (*it4 == 11) << endl;
程序的执行结果如下所示:

3.1.2 自定义类型元素的find
当我们需要查找的是自定义类型的元素时,在比较过程中,其实程序并不知道如何比较两个元素是否相等,也就是没有对应的==运算符。因此,我们需要在自定义类中重载==运算符:
//Person类
class Person {
public:
string name;
int age;
Person(string n, int a) : name(n), age(a){}
//重载==运算符
bool operator==(const Person &p) {
return (this->name == p.name) && (this->age == p.age);
}
};
//主函数
int main() {
vector<Person> vp;
Person p1("A", 18);
vp.push_back(p1);
Person p2("B", 18);
vp.push_back(p2);
Person p3("C", 18);
vp.push_back(p3);
Person p4("D", 18);
vp.push_back(p4);
Person p5("E", 18);
vp.push_back(p5);
//能找到的C
Person p_find("C", 18);
vector<Person>::iterator itp = find(vp.begin(), vp.end(), p_find)
6423




被折叠的 条评论
为什么被折叠?



