文章目录
前言
本章主要记录 STL中的常用算法,以及它们的用途
本章内容仅为学习记录,如有纰漏,欢迎指正
简介:
- 算法主要是由头文件<algorithm>,<functional>,<numeric>组成
- <algorithm>范围较大,涉及比较,交换,遍历,查找,复制,修改等
- <numeric>体积较小,只包括几个在序列上进行简单数学运算的模板函数
- <functional>定义了一些模板,用来声明函数对象
一.遍历
1.for_each
- 作用:遍历容器
- 定义:
for_each(InputIterator beg, InputIterator end, _Func);
- for_each第三个参数传仿函数,普通函数,lambda表达式都是可以的
例:
vector<int> vec;
for (int i = 0; i < 10; i++)
{
vec.push_back(i);
}
//for_each第三个参数传仿函数,普通函数,lambda表达式都是可以的
for_each(vec.begin(), vec.end(), [](int val) {
cout << val << " " ;
});
输出结果:
0 1 2 3 4 5 6 7 8 9
2.transform
- 作用:将容器数据搬运至另一个容器
- 定义:
OutputIterator transform(InputIterator beg, InputIterator end, OutputIterator destBeg, _Func);
- 注意这里需要先将目标容器的空间开辟好,算法内部不会自动自动开辟空间
vector<int> vec;
for (int i = 0; i < 10; i++)
{
vec.push_back(i);
}
vector<int> target;
//提前开辟空间
target.resize(vec.size());
//transform 的第四个参数是函数,返回值为容器的泛型类型
transform(vec.begin(), vec.end(), target.begin(), [](int val) {
return 10 - val;
});
for_each(target.begin(), target.end(), [](int val) {
cout << val << " ";
});
输出结果:
10 9 8 7 6 5 4 3 2 1
二.查找
1.find
- 作用:查找元素,返回迭代器,找不到返回end
- 定义:
InputIterator find(InputIterator beg, InputIterator end, const T& value);
- 底层使用"==" 号比较,如果需要比较自定义数据类型需重载 “==”
vector<int> vec;
for (int i = 0; i < 10; i++)
{
vec.push_back(i);
}
vector<int>::iterator it = find(vec.begin(), vec.end(), 9);
if(it == vec.end())
{
cout << "no find" << endl;
}
else
{
cout << *it << endl;
}
输出结果:
9
2.find_if
- 作用:按条件查找,返回迭代器,找不到返回end
- 定义:
InputIterator find_if(InputIterator beg, InputIterator end, _Pred);
- _Pred: 谓词(返回值为bool的仿函数),或者bool返回类型的函数
vector<int> vec;
for (int i = 0; i < 10; i++)
{
vec.push_back(i);
}
vector<int>::iterator it = find(vec.begin(), vec.end(), [](int val){
return val > 6;
});
if(it == vec.end())
{
cout << "no find" << endl;
}
else
{
cout << *it << endl;
}
输出结果:
7
3.adjacent_find
- 作用:查找相邻重复元素,返回相邻元素的第一个位置的迭代器
- 定义:
ForwardIterator adjacent_find(ForwardIterator beg, ForwardIterator end);
ForwardIterator adjacent_find(ForwardIterator beg, ForwardIterator end, _Pred);
vector<int> vec;
vec.push_back(9);
vec.push_back(6);
vec.push_back(6);
vec.push_back(4);
vec.push_back(9);
vec.push_back(1);
vec.push_back(1);
vector<int>::iterator it = adjacent_find(vec.begin(), vec.end());
if(it == vec.end())
{
cout << "no find" << endl;
}
else
{
cout << *it << endl;
}
//自定义查找
it = adjacent_find(vec.begin(), vec.end(), [](int num1, int num2){
return num1 == num2 - 2;
});
if(it == vec.end())
{
cout << "no find" << endl;
}
else
{
cout << *it << endl;
}
输出结果:
6
4
4.binary_search
- 作用:二分查找,查找指定元素,找到返回true,否则false
- 定义:
bool binary_search(RandomIterator beg, RandomIterator end, const T& value);
- 查找序列必须有序,否则返回结果未知
- 查找容器的迭代器必须为随机访问类型
vector<int> vec;
for (int i = 0; i < 10; i++)
{
vec.push_back(i);
}
if(binary_search(vec.begin(), vec.end(), 4))
{
cout << "find" << endl;
}
else
{
cout << "not be found" << endl;
}
输出结果:
find
5.count
- 作用:统计元素个数
- 定义:
int count(InputIterator beg, InputIterator end, const T& value);
vector<int> vec;
for (int i = 0; i < 10; i++)
{
vec.push_back(i);
}
cout << count(vec.begin(), vec.end(), 4) << endl;
输出结果:
1
6.count_if
- 作用:按条件统计元素个数
- 定义:
int count_if(InputIterator beg, InputIterator end, _Pred);
- _Pred:谓词或返回类型为 bool值的函数
vector<int> vec;
for (int i = 0; i < 10; i++)
{
vec.push_back(i);
}
cout << count(vec.begin(), vec.end(), [](int val){
return val > 5;
}) << endl;
输出结果:
4
三.排序
1.sort
- 作用:排序,可以手动制定排序规则(默认从小到大)
- 定义:
sort(RandomIterator beg, RandomIterator end, _Pred);
- 可以调用<functional>中的模板仿函数,快速的实现简单功能
vector<int> vec;
for (int i = 0; i < 10; i++)
{
vec.push_back(i);
}
sort(vec.begin(), vec.end(), greater<int>());
for_each(vec.begin(), vec.end(), [](int val){
cout << val << " ";
});
输出结果:
9 8 7 6 5 4 3 2 1 0
2.random_shuffle
- 作用:随机洗牌
- 定义:
random_shuffle(iterator beg, iterator end);
random_shuffle(iterator beg, iterator end, _Func);
- 没有啥深意,就是随机打乱,建议传入时间戳和随机种子,即可以真正意义上的打乱
vector<int> vec;
for (int i = 0; i < 10; i++)
{
vec.push_back(i);
}
//引入头文件<ctime>
srand((unsigned int)time(NULL));
//随机打乱
random_shuffle(vec.begin(), vec.end(), [](int i){
return rand() % i;
});
for_each(vec.begin(), vec.end(), [](int val){
cout << val << " ";
});
输出结果: 随机未知
3.merge
- 作用:容器元素合并,存储至另一个容器
- 定义:
merge(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
- 两个容器必须有序,且排序规则相同才可使用(归并思想实现)
vector<int> vec1;
vector<int> vec2;
for (int i = 0; i < 10; i++)
{
vec1.push_back(i);
vec2.push_back(i + 5);
}
vector<int> target;
target.resize(vec1.size() + vec2.size());
merge(vec1.begin(), vec1.end(), vec2.begin(), vec2.end(), target.begin());
for_each(target.begin(), target.end(), [](int val){
cout << val << " ";
});
输出结果:
0 1 2 3 4 5 5 6 6 7 7 8 8 9 9 10 11 12 13 14
4.reverse
- 作用:反转指定范围元素
- 定义:
reverse(BidirectionalIterator beg, BidirectionalIterator end);
vector<int> vec;
for (int i = 0; i < 10; i++)
{
vec.push_back(i);
}
reverse(vec.begin(), vec.end());
for_each(vec.begin(), vec.end(), [](int val){
cout << val << " ";
});
输出结果:
9 8 7 6 5 4 3 2 1 0
四.拷贝和替换
1.copy
- 作用:指定范围元素拷贝
- 定义:
OutputIterator copy(InputIterator beg, InputIterator end, OutputIterator dest);
vector<int> vec;
for (int i = 0; i < 10; i++)
{
vec.push_back(i);
}
vector<int> target;
target.resize(vec.size());
copy(vec.begin(), vec.end(), target.begin());
for_each(target.begin(), target.end(), [](int val){
cout << val << " ";
});
输出结果:
0 1 2 3 4 5 6 7 8 9
2.replace
- 作用:指定范围所有目标元素修改为新元素
- 定义:
replace(const_iterator beg, const_iterator end, const T& val);
replace(const_iterator beg, const_iterator end, T& oldvalue, const T& newvalue);
replace(size_t pos, size_t len, const T& val);
vector<int> vec;
for (int i = 0; i < 10; i++)
{
vec.push_back(i);
}
//第二种方式
replace(vec.begin(), vec.end(), 1, 100);
for_each(vec.begin(), vec.end(), [](int val){
cout << val << " ";
});
输出结果:
0 100 2 3 4 5 6 7 8 9
3.replace_if
- 作用:指定范围所有满足条件的元素修改为新元素
- 定义:
replace(iterator beg, iterator end, _Pred, newvalue);
- _Pred: 谓词或 返回值为bool类型的函数
vector<int> vec;
for (int i = 0; i < 10; i++)
{
vec.push_back(i);
}
replace(vec.begin(), vec.end(), [](int val){
return val > 5;
}, 100);
for_each(vec.begin(), vec.end(), [](int val){
cout << val << " ";
});
输出结果:
0 1 2 3 4 5 100 100 100 100
4.swap
- 作用:元素互换
- 定义:
swap(T& c1, T& c2);
vector<int> vec1;
vector<int> vec2;
for (int i = 0; i < 10; i++)
{
vec1.push_back(i);
vec2.push_back(10 - i);
}
swap(vec1, vec2);
for(int i = 0; i < vec1.size(); i++)
{
cout << vec1[i] << " " << vec2[i] << endl;
}
输出结果:
10 0
9 1
8 2
7 3
6 4
5 5
4 6
3 7
2 8
1 9
五.算术生成
- 注意以下算法均需要包含<numeric>头文件
1.accumulate
- 作用:计算并返回容器元素累计总和,也可以用于字符串连接
- 定义:
T accumulate(InputIterator beg, InputIterator end, const T& value);
T accumulate(InputIterator beg, InputIterator end, const T& value, _Func);
- value为初始值
vector<int> vec;
for (int i = 1; i <= 10; i++)
{
vec.push_back(i);
}
//默认为加法
cout << accumulate(vec.begin(), vec.end(), 0) << endl;
//乘积
cout << accumulate(vec.begin(), vec.end(), 1, multiplies<int>()) << endl;
//自定义加法
cout << accumulate(vec.begin(), vec.end(), 1, [](int acc, int num){
return acc + num;
}) << endl;
输出结果:
55
3628800
55
2.fill
- 作用:向容器区间内赋值为相同元素,相比assign,fill可以用于给数组赋值,而assign不行
- 定义:
fill(InputIterator beg, InputIterator end, const T& value);
- 在对多维数组赋值时,可以直接计算内存空间,传入指针赋值即可
vector<int> vec;
vec.resize(5);
fill(vec.begin(), vec.end(), 10);
for_each(vec.begin(), vec.end(), [](int val){
cout << val << " ";
});
输出结果:
10 10 10 10 10
六.两容器的集合
- 注:以下所有方法中,target容器都需要事先开辟好空间
1.set_intersection
- 作用:求两容器的交集,返回target容器的结束位置迭代器
- 定义:
iterator set_intersection(InputIterator beg1, InputIterator end1, InputIterator beg2, InputIterator end2, OutputIterator dest);
- 使用时两个目标容器必须有序
vector<int> vec1;
vector<int> vec2;
for(int i = 0; i < 10; i++)
{
vec1.push_back(i);
vec2.push_back(i + 5);
}
vector<int> target;
//交集的空间大小不可能超过两个容器中,较小容器的大小
target.resize(min(vec1.size(), vec2.size()));
auto IEnd = set_intersection(vec1.begin(), vec1.end(), vec2.begin(), vec2.end(), target.begin());
for_each(target.begin(), IEnd, [](int val){
cout << val << " ";
});
输出结果:
5 6 7 8 9
2.set_union
- 作用:求两容器的并集,返回target容器的结束位置迭代器
- 定义:
iterator set_union(InputIterator beg1, InputIterator end1, InputIterator beg2, InputIterator end2, OutputIterator dest);
- 使用时两个目标容器必须有序
vector<int> vec1;
vector<int> vec2;
for(int i = 0; i < 10; i++)
{
vec1.push_back(i);
vec2.push_back(i + 5);
}
vector<int> target;
//并集的空间大小不可能超过两个容器大小的和
target.resize(vec1.size() + vec2.size());
auto IEnd = set_union(vec1.begin(), vec1.end(), vec2.begin(), vec2.end(), target.begin());
for_each(target.begin(), IEnd, [](int val){
cout << val << " ";
});
输出结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
3.set_difference
- 作用:求两容器的差集,返回target容器的结束位置迭代器
- 定义:
iterator set_difference(InputIterator beg1, InputIterator end1, InputIterator beg2, InputIterator end2, OutputIterator dest);
- 使用时两个目标容器必须有序
vector<int> vec1;
vector<int> vec2;
for(int i = 0; i < 10; i++)
{
vec1.push_back(i);
vec2.push_back(i + 5);
}
vector<int> target;
//差集的空间大小不可能超过两个容器中,较大容器的大小
target.resize(max(vec1.size(), vec2.size()));
auto IEnd = set_difference(vec1.begin(), vec1.end(), vec2.begin(), vec2.end(), target.begin());
for_each(target.begin(), IEnd, [](int val){
cout << val << " ";
});
输出结果:
1 2 3 4 5
总结
真好玩,就是有点费脑子