黑马C++笔记——STL常用算法
2023-09-14 09:14:58 时间
STL常用算法
1.概述
- STL算法主要是由头文件algorithm functional numeric组成
- algorithm 是所有STL文件中最大的一个,涉及到比较、交换、查找、遍历、复制、修改等操作
- numeric 比较小,只包含了几个在序列上面进行简单数学运算的模板函数
- functional 定义了一些模板类,用以声明函数对象
2.常用算法
1.常用遍历算法
- for_each 遍历容器
- transform 搬运一个容器中的元素 到 另一个容器中
1.for_each
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
void print01(int val) {
cout << val << " ";
}
class print02 {
public:
void operator() (int val) {
cout << val << " ";
}
};
void test() {
vector<int> v{ 1,2,3,4,5,6,7,8,9,10 };
//1.利用普通函数 for_each
for_each(v.begin(), v.end(), print01);
cout << endl;
cout << "-----------------------------------------------" << endl;
//2.利用仿函数遍历
for_each(v.begin(), v.end(), print02());
cout << endl;
}
int main() {
test();
system("pause");
return 0;
}
2.transform
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
class Transform {
public:
int operator() (int val) {
return val;
}
};
class Print {
public:
void operator()(int val) {
cout << val << " ";
}
};
void test() {
vector<int> v{ 1,2,3,4,5,6,7,8,9,10 };
vector<int> target;
//利用transform 将容器v 中的元素 搬到target中
//提前分配足够的容量
target.resize(v.size());
//开始搬运
transform(v.begin(), v.end(), target.begin(), Transform());
//遍历输出
for_each(target.begin(), target.end(), Print());
cout << endl;
}
int main() {
test();
system("pause");
return 0;
}
2.常用查找算法
- find 查找元素
- find_if 按照条件查找元素
- adjacent_find 查找相邻的重复元素
- binary_search 二分查找元素
- count 统计元素个数
- count_if 按条件统计元素个数
1.find
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
//1.查找内置数据类型
void test01() {
vector<int> v{ 1,2,3,4,5,6,7,8,9,10 };
//查找是否存在元素6
auto it = find(v.begin(), v.end(), 6);
if (it == v.end()) {
cout << "容器中没有元素6" << endl;
}
else {
cout << "找到了:" << *it << endl;
}
}
class Person {
public:
string name;
int age;
Person(string name, int age) {
this->name = name;
this->age = age;
}
bool operator== (const Person& p) {
return this->name == p.name && this->age == p.age;
}
};
//2.查找自定义数据类型
void test02() {
vector<Person> v;
Person p1("wurusai", 20);
Person p2("zed", 45);
Person p3("yassuo", 30);
Person p4("leesin", 50);
Person p5("pyke", 100);
v.push_back(p1);
v.push_back(p2);
v.push_back(p3);
v.push_back(p4);
v.push_back(p5);
Person pp("wurusai", 20);
//查找是否存在pp
auto it = find(v.begin(), v.end(), pp);
if (it == v.end()) {
cout << "容器中没有pp这个元素" << endl;
}
else {
cout << "找到了:name = " << it->name << " , age = " << it->age << endl;
}
}
int main() {
//test01();
test02();
system("pause");
return 0;
}
2.find_if
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
class GreaterFive {
public:
bool operator()(int val) {
return val > 5;
}
};
//1.查找内置数据类型
void test01() {
vector<int> v{ 1,2,3,4,5,6,7,8,9,10 };
//查找是否有 大于 5 的元素
auto it = find_if(v.begin(), v.end(), GreaterFive());
if (it == v.end()) {
cout << "该容器中没有大于5的元素" << endl;
}
else {
cout << "找到了大于5的元素:" << *it << endl;
}
}
class Person {
public:
int age;
string name;
Person(int age, string name) {
this->age = age;
this->name = name;
}
};
class Greater30 {
public:
bool operator() (const Person& p) {
return p.age > 30;
}
};
//2.查找自定义类型
void test02() {
vector<Person> v;
Person p1(10, "aaa");
Person p2(20, "bbb");
Person p3(30, "ccc");
Person p4(40, "ddd");
Person p5(50, "eee");
//查找是否有年龄大于30的元素
v.push_back(p1);
v.push_back(p2);
v.push_back(p3);
v.push_back(p4);
v.push_back(p5);
auto it = find_if(v.begin(), v.end(), Greater30());
if (it == v.end()) {
cout << "没有年龄大于30的元素" << endl;
}
else {
cout << "找到了年龄大于30的元素:name = " << it->name << " , age = " << it->age << endl;
}
}
int main() {
//test01();
test02();
system("pause");
return 0;
}
3.adjacent_find
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
void test() {
vector<int> v{ 1,2,3,4,5,6,6,7,7,8,8 };
//查找相邻重复元素
//注意:只能找到第一个相邻重复的元素
auto it = adjacent_find(v.begin(), v.end());
if (it == v.end()) {
cout << "容器中没有重复相邻元素" << endl;
}
else {
cout << "找到了:" << *it << endl; //6
}
}
int main() {
test();
system("pause");
return 0;
}
4.binary_search
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
void test() {
vector<int> v{ 1,2,3,4,5,6,7,8,8,8,9,10 };
//查找元素 8 是否存在
bool ok = binary_search(v.begin(), v.end(), 8); // 注意:该函数只能用于有序序列
if (ok) {
cout << "存在" << endl;
}
else {
cout << "不存在" << endl;
}
}
int main() {
test();
system("pause");
return 0;
}
5.count
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
//1.统计内置数据类型个数
void test01() {
vector<int> v{ 1,2,3,4,5,6,7,7,7,7,8,7,8,8,7 };
//统计元素7的个数
int cnt = count(v.begin(), v.end(), 7);
cout << "元素7 的个数为:" << cnt << endl;//6
}
class Person {
public:
int age;
string name;
Person(int age, string name) {
this->age = age;
this->name = name;
}
bool operator== (const Person& p) {
return this->age== p.age;
}
};
//2.统计自定义数据类型的个数
void test02() {
vector<Person> v;
Person p1(20, "wurusai");
Person p2(30, "zed");
Person p3(40, "aaa");
Person p4(20, "bbb");
Person p5(20, "ccc");
v.push_back(p1);
v.push_back(p2);
v.push_back(p3);
v.push_back(p4);
v.push_back(p5);
//统计与 Tom 年龄相等的人的数量
int cnt = count(v.begin(), v.end(), Person(20, "Tom"));
cout << "与Tom年龄相同的人数:" << cnt << endl;//3
}
int main() {
//test01();
test02();
system("pause");
return 0;
}
6.count_if
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
class Greater5 {
public:
bool operator() (int val) {
return val > 5;
}
};
//统计内置数据类型
void test01() {
vector<int> v{ 1,2,3,4,5,6,7,8,9,10 };
//统计大于5的元素个数
int cnt = count_if(v.begin(), v.end(), Greater5());
cout << "大于5的元素个数为:" << cnt << endl;
}
class Person {
public:
int age;
string name;
Person(int age, string name) {
this->age = age;
this->name = name;
}
};
class AgeGreater20 {
public:
bool operator() (const Person& p) {
return p.age > 20;
}
};
//统计自定义类型
void test02() {
vector<Person> v;
Person p1(20, "aaa");
Person p2(15, "bbb");
Person p3(26, "ccc");
Person p4(33, "eee");
Person p5(25, "ddd");
v.push_back(p1);
v.push_back(p2);
v.push_back(p3);
v.push_back(p4);
v.push_back(p5);
int cnt = count_if(v.begin(), v.end(), AgeGreater20());
cout << "年龄大于20的人数为:" << cnt << endl;
}
int main() {
//test01();
test02();
system("pause");
return 0;
}
3.常见排序算法
- sort 对容器内的元素进行排序(默认是升序)
- random_shuffle 将指定范围内的元素随机打乱
- merge 将两个容器的元素合并到另外一个容器中
- reverse 反转指定范围的元素
1.sort
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
void test() {
vector<int> v{ 7,5,12,3,6,4,9,5,1,2,3,5,11,23 };
//升序排序
sort(v.begin(), v.end());
//for_each 用lambda表达式输出
for_each(v.begin(), v.end(), [](int val) {
cout << val << " ";
});
cout << endl;
//降序排序
sort(v.begin(), v.end(), greater<int>());
for_each(v.begin(), v.end(), [](int val) {
cout << val << " ";
});
cout << endl;
}
int main() {
test();
system("pause");
return 0;
}
2.random_shuffle
#include<iostream>
#include<algorithm>
#include<vector>
#include<ctime>
using namespace std;
//随机打乱 容器中的元素
void test() {
//随机数种子
srand((unsigned int)time(nullptr));
vector<int> v{ 1,2,3,4,5,6,7,8,9,10 };
//洗牌
random_shuffle(v.begin(), v.end());
//输出
for_each(v.begin(), v.end(), [](int val) {
cout << val << " ";
});
cout << endl;
}
int main() {
test();
system("pause");
return 0;
}
3.merge
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
void test() {
//merge 将两个有序列表 合并到 一个列表中(还是有序的)
vector<int> v1{ 1,3,5,7,9,11,13,15 }, v2{ 0,2,4,6,8,10,12,14 };
vector<int> t;
//预留足够的空间
t.resize(v1.size() + v2.size());
//merge
merge(v1.begin(), v1.end(), v2.begin(), v2.end(), t.begin());
//遍历
for_each(t.begin(), t.end(), [](int val) {
cout << val << " ";
});
cout << endl;
}
int main() {
test();
system("pause");
return 0;
}
4.reverse
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
void test() {
//reverse 反转
vector<int> v{ 1,2,3,4,5,6,7,8,9,10 };
cout << "反转前:" << endl;
for_each(v.begin(), v.end(), [](int val) {
cout << val << " ";
});
cout << endl;
reverse(v.begin(), v.end());
cout << "反转后:" << endl;
for_each(v.begin(), v.end(), [](int val) {
cout << val << " ";
});
cout << endl;
}
int main() {
test();
system("pause");
return 0;
}
4.常见的拷贝替换算法
- copy 将容器指定范围的元素拷贝到另一个容器当中去
- replace 将指定范围内的元素替换为新的元素
- replace_if 将指定范围内的满足条件的元素替换为新的元素
- swap 互换两个容器的元素
1.copy
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
void test() {
vector<int> v{ 1,2,3,4,5,6,7,8,9,10 };
vector<int> t;
//预留足够的空间
t.resize(v.size());
//copy
copy(v.begin(), v.end(), t.begin());
//输出
for_each(t.begin(), t.end(), [](int val) {
cout << val << " ";
});
cout << endl;
}
int main() {
test();
system("pause");
return 0;
}
2.replace
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
class MyPrint {
public:
void operator()(int val) {
cout << val << " ";
}
};
void test() {
vector<int> v{ 1,2,3,4,5,5,5,6,6,4,5,7,5,1 };
cout << "替换前:" << endl;
for_each(v.begin(), v.end(), MyPrint());
//将 5 替换为 -1
replace(v.begin(), v.end(), 5, -1);
cout << "替换后:" << endl;
for_each(v.begin(), v.end(), MyPrint());
}
int main() {
test();
system("pause");
return 0;
}
3.replace_if
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
class MyPrint {
public:
void operator()(int val) {
cout << val << " ";
}
};
class Greater5 {
public:
bool operator()(int val) {
return val >= 5;
}
};
void test() {
vector<int> v{ 1,2,3,4,5,5,5,6,6,4,5,7,5,1 };
cout << "替换前:" << endl;
for_each(v.begin(), v.end(), MyPrint());
cout << endl;
//将 大于等于5的元素 替换为 -1
replace_if(v.begin(), v.end(), Greater5(), -1);
cout << "替换后:" << endl;
for_each(v.begin(), v.end(), MyPrint());
cout << endl;
}
int main() {
test();
system("pause");
return 0;
}
4.swap
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
class MyPrint {
public:
void operator()(int val) {
cout << val << " ";
}
};
void test() {
vector<int> v1{ 1,2,3,4,5,5,5,6,6,4,5,7,5,1 };
vector<int> v2{ 100,111,112,113,56,12 };
cout << "交换前:" << endl;
for_each(v1.begin(), v1.end(), MyPrint());
cout << endl;
for_each(v2.begin(), v2.end(), MyPrint());
cout << endl;
//交换
cout << "-----------------------------------------------------" << endl;
v1.swap(v2);
cout << "交换后:" << endl;
for_each(v1.begin(), v1.end(), MyPrint());
cout << endl;
for_each(v2.begin(), v2.end(), MyPrint());
cout << endl;
}
int main() {
test();
system("pause");
return 0;
}
5.常用算数算法
- accumulate 计算容器内元素的累加和
- fill 填充容器
1.accumulate
#include<iostream>
#include<algorithm>
#include<vector>
#include<numeric>
using namespace std;
void test() {
vector<int> v;
for (int i = 0; i <= 100; i++) v.push_back(i);
//元素的累加和
int sum = accumulate(v.begin(), v.end(), 0);
cout << "sum = " << sum << endl; //5050
}
int main() {
test();
system("pause");
return 0;
}
2.fill
#include<iostream>
#include<algorithm>
#include<vector>
#include<numeric>
using namespace std;
void test() {
vector<int> v(10);
//填充为指定元素
fill(v.begin(), v.end(), 10);
//遍历
for_each(v.begin(), v.end(), [](int val) {
cout << val << " ";
});
cout << endl;
}
int main() {
test();
system("pause");
return 0;
}
6.常见集合算法
- set_intersection 求两个集合的交集
- set_union 求两个集合的并集
- set_difference 求两个集合的差集
1.set_intersection
#include<iostream>
#include<algorithm>
#include<vector>
#include<numeric>
using namespace std;
void test() {
//求两个集合的交集
vector<int> v1{ 1,2,3,4,5,6,7,8,9 }, v2{ 2,2,2,3,3,3,6,7,8,9 };
vector<int> t;
t.resize(v1.size() + v2.size());
//求交集
auto itEnd = set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), t.begin());
//遍历输出
for_each(t.begin(), itEnd, [](int val) {
cout << val << " ";
});
cout << endl;
}
int main() {
test();
system("pause");
return 0;
}
2.set_union
#include<iostream>
#include<algorithm>
#include<vector>
#include<numeric>
using namespace std;
void test() {
//求两个集合的并集
vector<int> v1{ 1,3,5,7,9 }, v2{ 2,4,6,8,10 };
vector<int> t;
t.resize(v1.size() + v2.size());
//求并集
auto itEnd = set_union(v1.begin(), v1.end(), v2.begin(), v2.end(), t.begin());
//遍历输出
for_each(t.begin(), itEnd, [](int val) {
cout << val << " ";
});
cout << endl;
}
int main() {
test();
system("pause");
return 0;
}
3.set_difference
#include<iostream>
#include<algorithm>
#include<vector>
#include<numeric>
using namespace std;
void test() {
//求两个集合的差集
vector<int> v1{ 1,2,3,4,5,6,7,8,9 }, v2{ 7,8,9,10,11,12,13 };
vector<int> t;
t.resize(max(v1.size() , v2.size()));
//求并集
auto itEnd = set_difference(v1.begin(), v1.end(), v2.begin(), v2.end(), t.begin());
//v1 - v2
for_each(t.begin(), itEnd, [](int val) {
cout << val << " ";
});
cout << endl;
cout << "-----------------------------------------" << endl;
//求并集
itEnd = set_difference(v2.begin(), v2.end(), v1.begin(), v1.end(), t.begin());
//v2 - v1
for_each(t.begin(), itEnd, [](int val) {
cout << val << " ";
});
cout << endl;
}
int main() {
test();
system("pause");
return 0;
}
相关文章
- C++学习——c++逗号操作符说明(附加全部运算符优先级)
- EasyC++02,C++常用语句简介
- 猴子吃桃 -- C++ 算法
- C++ mysql connector使用方法「建议收藏」
- 银行家算法C++实现
- 【C++】0314算法阿里笔试题「建议收藏」
- 使用 C 或 C++ 扩展 Python
- C++结构体和类的区别_c++有结构体吗
- C/C++语言常用排序算法
- C++不知算法系列之高精度数值的加、减、乘、除算法
- C/C++ 编写并提取简易 ShellCode
- C/C++ 数据结构与算法笔记
- C/C++ 常用加解密算法收集
- Xmake v2.7.3 发布,包组件和 C++ 模块增量构建支持
- C/C++生态工具链——接口模拟工具gmock
- 数据结构小记【Python/C++版】——B树篇
- 【C++修炼之路】9. string类的模拟实现
- C++引用类型详解
- C++ sort(STL sort)排序算法详解
- C++ find_first_of(STL find_first_of)查找算法详解
- C++ lower_bound(STL lower_bound)二分查找算法详解
- C++冒泡排序数据结构、算法及改进算法
- 深入分析C++中两个大数相乘结果不正确的问题
- C++大数模板(推荐)
- 海量数据处理系列之:用C++实现Bitmap算法
- C++基本算法思想之递推算法思想
- c++生成dll使用python调用dll的方法
- c++非变易算法-stl算法
- c++11新增的便利算法实例分析